Skip to content

CI Integration

This guide shows how to add lexicon verify to a GitHub Actions workflow so that every push and pull request is verified against your contracts and gates.

Create .github/workflows/lexicon.yml:

name: Lexicon Verify
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
components: rustfmt, clippy
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/
~/.cargo/git/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install Lexicon
run: cargo install --path crates/cli
- name: Run Verify
run: lexicon verify --health

The lexicon verify step executes:

  1. All gates defined in specs/gates.toml (fmt, clippy, tests, etc.)
  2. Score computation from specs/scoring/model.toml
  3. Audit record written to .lexicon/audit/

The default gates run cargo fmt -- --check, cargo clippy -- -D warnings, cargo test, and cargo test --doc.

Currently lexicon verify exits with status 0 regardless of gate outcomes. To fail CI on gate failures, wrap the command:

- name: Run Verify
run: |
lexicon verify 2>&1 | tee verify-output.txt
if grep -q "Some gates failed" verify-output.txt; then
echo "Verification failed"
exit 1
fi

The --health flag on lexicon verify is optional but recommended. It adds checks for:

  • Manifest exists
  • Gates are configured
  • Scoring model is configured
  • CLAUDE.md is present
  • API baseline is present

This catches configuration drift early.

The cargo cache step speeds up subsequent runs by caching:

  • Compiled dependencies in target/
  • Cargo registry and git checkouts
  • The lexicon binary in ~/.cargo/bin/

Each lexicon verify run writes an audit record to .lexicon/audit/. In CI, these records are written but not committed back to the repository. If you want to preserve CI audit records, add a step to commit them or upload as artifacts:

- name: Upload Audit Records
if: always()
uses: actions/upload-artifact@v4
with:
name: lexicon-audit
path: .lexicon/audit/

For local verification before pushing, add a git pre-commit hook:

.git/hooks/pre-commit
#!/bin/sh
lexicon verify

Or with health checks:

.git/hooks/pre-commit
#!/bin/sh
lexicon verify --health