Skip to main content

Compile CLAUDE.md into enforceable repo policy for Claude Code

Project description

claude-md-compiler

Compile CLAUDE.md into a versioned lockfile. Enforce it on local edits, staged diffs, and CI.

PyPI Python License: MIT

cldc preview

cldc turns the rules in your CLAUDE.md into a deterministic policy lockfile, then checks runtime activity (reads, writes, commands, git diffs) against it. The same lockfile gates a local edit, a pre-commit hook, and a pull request.

Install

cldc is a CLI you install once and point at any repo whose CLAUDE.md you want to enforce.

# Persistent install (recommended)
uv tool install claude-md-compiler        # or: pipx install claude-md-compiler
                                          # or: pip install claude-md-compiler

# One-shot, no install
uvx --from claude-md-compiler cldc compile .

Verify with cldc --version. Requires Python 3.11+. The only runtime dependency is PyYAML.

Run these in your project, not inside a clone of this repo. From inside the source tree, uv add claude-md-compiler errors with "self-dependencies are not permitted" — use the Develop workflow instead.

Quick start

# 1. Compile policy from CLAUDE.md + policies/*.yml
cldc compile .

# 2. Check a change against it
cldc check . --write src/main.py --command "pytest -q"

# 3. Gate a pull request
cldc ci . --base origin/main --head HEAD

Exit codes: 0 clean or warn-only · 1 runtime error · 2 blocking violations.

How it works

 sources                                   evidence
 ─────────────────────                     ───────────────────────────
 CLAUDE.md (cldc blocks)                   --read / --write / --command
 .claude-compiler.yaml                     --events-file / --stdin-json
 policies/*.yml                            git diff (staged | base..head)
          │                                            │
          ▼                                            ▼
    cldc compile                               cldc check  /  cldc ci
          │                                            │
          ▼                                            ▼
 .claude/policy.lock.json  ───────────────▶   pass · warn · block
                                                       │
                                           ┌───────────┴───────────┐
                                           ▼                       ▼
                                     cldc explain              cldc fix
                                   (text · md · json)      (remediation plan)

Three stages: discover sources, compile them into a digest-stable lockfile, enforce it against execution evidence. Reports are deterministic and reusable — explain and fix consume saved JSON without re-running enforcement.

Commands

Command Purpose
cldc compile [repo] Parse sources, write .claude/policy.lock.json.
cldc doctor [repo] Diagnose discovery, parsing, and lockfile state.
cldc check [repo] Evaluate runtime evidence against the policy.
cldc ci [repo] Same as check, but read changed files from git diff.
cldc explain [repo] Render a saved or fresh report as text or markdown.
cldc fix [repo] Build a deterministic remediation plan from a report.

Every command takes --json and --output <file> for machine-readable, persistable results.

Writing rules

Rules live inline in CLAUDE.md, in .claude-compiler.yaml, or in policies/*.yml. They merge in that order, deterministically.

# CLAUDE.md

```cldc
rules:
  - id: generated-lock
    kind: deny_write
    mode: block
    paths: ["generated/**"]
    message: Generated files are produced by the build — don't edit them.
```
# policies/commands.yml
rules:
  - id: run-tests
    kind: require_command
    commands: ["pytest -q"]
    when_paths: ["src/**", "tests/**"]
    message: Run tests before finishing.
Kind What it asserts
deny_write A path glob must not be written.
require_read A path must be read before another path is written.
require_command A command must run when matching paths are touched.
couple_change Editing one path requires editing another.
Mode Behavior
observe Recorded only. No exit-code change.
warn Reported, exit 0. (default)
block Reported, exit 2.
fix Reported with a remediation plan from cldc fix.

Feeding evidence

check, explain, and fix accept evidence three ways. Mix and match.

# Direct flags
cldc check . --read docs/spec.md --write src/main.py --command "pytest -q"

# JSON file  (read_paths, write_paths, commands, claims, or events[])
cldc check . --events-file .cldc-events.json

# Stdin
cat .cldc-events.json | cldc check . --stdin-json

Save a report once, reuse it everywhere:

cldc check . --events-file .cldc-events.json --json --output artifacts/report.json
cldc explain . --report-file artifacts/report.json --format markdown --output artifacts/report.md
cldc fix     . --report-file artifacts/report.json --format markdown --output artifacts/fix.md

CI

# .github/workflows/policy.yml
name: policy
on: pull_request

jobs:
  cldc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: astral-sh/setup-uv@v6
      - run: uv sync
      - run: uv run cldc compile .
      - name: Enforce
        run: |
          set +e
          uv run cldc ci . \
            --base origin/${{ github.base_ref }} --head ${{ github.sha }} \
            --json --output artifacts/policy-report.json
          status=$?
          uv run cldc explain . \
            --report-file artifacts/policy-report.json \
            --format markdown --output artifacts/policy-explanation.md
          exit $status

cldc ci is the enforcement edge. cldc explain turns the saved JSON into a review artifact before the job exits with the original policy status.

Develop

git clone https://github.com/AbdelStark/claude-md-compiler
cd claude-md-compiler
uv sync                       # creates .venv and installs cldc in editable mode
uv run pytest                 # full test suite

# Run the local build against a bundled fixture
uv run cldc compile tests/fixtures/repo_a
uv run cldc check   tests/fixtures/repo_a \
  --write src/main.py \
  --read  docs/rfcs/CLDC-0006-validator-engine.md \
  --command "pytest -q"

# Or activate the venv and call cldc directly
source .venv/bin/activate
cldc --version

uv sync installs the package editable, so source edits take effect immediately — no rebuild needed. Layout: src/cldc/{ingest,parser,compiler,runtime,cli}. RFCs that define the contracts live in docs/rfcs/.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_md_compiler-0.1.0.tar.gz (42.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_md_compiler-0.1.0-py3-none-any.whl (30.9 kB view details)

Uploaded Python 3

File details

Details for the file claude_md_compiler-0.1.0.tar.gz.

File metadata

  • Download URL: claude_md_compiler-0.1.0.tar.gz
  • Upload date:
  • Size: 42.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for claude_md_compiler-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7e4cdb71c30ae159bd7b7a26a55dccad9ebc217000986d05d49b8f24587836ac
MD5 bb4108198d2494806bcf48ecf85915d1
BLAKE2b-256 e1b367459663fd94914e05bc70b9bf993c8c5d778f7dc95969b99fc01782f4df

See more details on using hashes here.

File details

Details for the file claude_md_compiler-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: claude_md_compiler-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for claude_md_compiler-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1ab39394471d72a365d3560c84e41fc62ee511f2f2fe20d72099514159c6f07
MD5 f83ad909e0dcde37a41a6c6bc76fca4e
BLAKE2b-256 18de46fcd7a79c00c3dc7f2b0643fc2003375c7310b9c462ca43883e3bddff1e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page