claude-md-compiler 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_md_compiler-0.1.0/LICENSE +21 -0
- claude_md_compiler-0.1.0/PKG-INFO +230 -0
- claude_md_compiler-0.1.0/README.md +204 -0
- claude_md_compiler-0.1.0/docs/plans/2026-04-04-cldc-cron-log.md +266 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0001-policy-source-model.md +36 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0002-rule-dsl-v1.md +37 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0003-compiler-ir-and-lockfile.md +36 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0004-repo-scanner-and-topology-index.md +35 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0005-execution-event-model.md +35 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0006-validator-engine.md +35 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0007-enforcement-modes.md +36 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0008-fix-suggestions-and-autofix-hooks.md +34 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0009-cli-surface.md +38 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0010-ci-and-git-integration.md +35 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0011-explainability-report-model.md +34 -0
- claude_md_compiler-0.1.0/docs/rfcs/CLDC-0012-preset-packs.md +34 -0
- claude_md_compiler-0.1.0/docs/rfcs/README.md +16 -0
- claude_md_compiler-0.1.0/docs/screenshot.svg +18 -0
- claude_md_compiler-0.1.0/docs/specs/product-spec.md +118 -0
- claude_md_compiler-0.1.0/pyproject.toml +57 -0
- claude_md_compiler-0.1.0/src/cldc/__init__.py +25 -0
- claude_md_compiler-0.1.0/src/cldc/cli/__init__.py +0 -0
- claude_md_compiler-0.1.0/src/cldc/cli/main.py +412 -0
- claude_md_compiler-0.1.0/src/cldc/compiler/__init__.py +0 -0
- claude_md_compiler-0.1.0/src/cldc/compiler/policy_compiler.py +277 -0
- claude_md_compiler-0.1.0/src/cldc/ingest/__init__.py +0 -0
- claude_md_compiler-0.1.0/src/cldc/ingest/discovery.py +94 -0
- claude_md_compiler-0.1.0/src/cldc/ingest/source_loader.py +114 -0
- claude_md_compiler-0.1.0/src/cldc/parser/__init__.py +0 -0
- claude_md_compiler-0.1.0/src/cldc/parser/rule_parser.py +140 -0
- claude_md_compiler-0.1.0/src/cldc/policy/__init__.py +0 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/__init__.py +19 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/evaluator.py +425 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/events.py +114 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/git.py +66 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/remediation.py +317 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/report_schema.py +4 -0
- claude_md_compiler-0.1.0/src/cldc/runtime/reporting.py +319 -0
- claude_md_compiler-0.1.0/tests/fixtures/repo_a/.claude-compiler.yaml +11 -0
- claude_md_compiler-0.1.0/tests/fixtures/repo_a/CLAUDE.md +13 -0
- claude_md_compiler-0.1.0/tests/fixtures/repo_a/policies/commands.yml +7 -0
- claude_md_compiler-0.1.0/tests/smoke_test.py +28 -0
- claude_md_compiler-0.1.0/tests/test_cli.py +933 -0
- claude_md_compiler-0.1.0/tests/test_compiler.py +64 -0
- claude_md_compiler-0.1.0/tests/test_rule_parser.py +48 -0
- claude_md_compiler-0.1.0/tests/test_runtime.py +367 -0
- claude_md_compiler-0.1.0/tests/test_source_loader.py +53 -0
- claude_md_compiler-0.1.0/tests/test_validation.py +184 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AbdelStark
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: claude-md-compiler
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Compile CLAUDE.md into enforceable repo policy for Claude Code
|
|
5
|
+
Keywords: claude,policy,cli,compiler,ci,automation
|
|
6
|
+
Author: Hermes Agent
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Requires-Dist: pyyaml>=6.0
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Project-URL: Homepage, https://github.com/AbdelStark/claude-md-compiler
|
|
23
|
+
Project-URL: Repository, https://github.com/AbdelStark/claude-md-compiler
|
|
24
|
+
Project-URL: Issues, https://github.com/AbdelStark/claude-md-compiler/issues
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
<div align="center">
|
|
28
|
+
|
|
29
|
+
# claude-md-compiler
|
|
30
|
+
|
|
31
|
+
**Compile `CLAUDE.md` into a versioned lockfile. Enforce it on local edits, staged diffs, and CI.**
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/claude-md-compiler/)
|
|
34
|
+
[](https://www.python.org/)
|
|
35
|
+
[](./LICENSE)
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
`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.
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
`cldc` is a CLI you install once and point at any repo whose `CLAUDE.md` you want to enforce.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Persistent install (recommended)
|
|
49
|
+
uv tool install claude-md-compiler # or: pipx install claude-md-compiler
|
|
50
|
+
# or: pip install claude-md-compiler
|
|
51
|
+
|
|
52
|
+
# One-shot, no install
|
|
53
|
+
uvx --from claude-md-compiler cldc compile .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Verify with `cldc --version`. Requires Python 3.11+. The only runtime dependency is PyYAML.
|
|
57
|
+
|
|
58
|
+
> 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](#develop) workflow instead.
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 1. Compile policy from CLAUDE.md + policies/*.yml
|
|
64
|
+
cldc compile .
|
|
65
|
+
|
|
66
|
+
# 2. Check a change against it
|
|
67
|
+
cldc check . --write src/main.py --command "pytest -q"
|
|
68
|
+
|
|
69
|
+
# 3. Gate a pull request
|
|
70
|
+
cldc ci . --base origin/main --head HEAD
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Exit codes: `0` clean or warn-only · `1` runtime error · `2` blocking violations.
|
|
74
|
+
|
|
75
|
+
## How it works
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
sources evidence
|
|
79
|
+
───────────────────── ───────────────────────────
|
|
80
|
+
CLAUDE.md (cldc blocks) --read / --write / --command
|
|
81
|
+
.claude-compiler.yaml --events-file / --stdin-json
|
|
82
|
+
policies/*.yml git diff (staged | base..head)
|
|
83
|
+
│ │
|
|
84
|
+
▼ ▼
|
|
85
|
+
cldc compile cldc check / cldc ci
|
|
86
|
+
│ │
|
|
87
|
+
▼ ▼
|
|
88
|
+
.claude/policy.lock.json ───────────────▶ pass · warn · block
|
|
89
|
+
│
|
|
90
|
+
┌───────────┴───────────┐
|
|
91
|
+
▼ ▼
|
|
92
|
+
cldc explain cldc fix
|
|
93
|
+
(text · md · json) (remediation plan)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
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.
|
|
97
|
+
|
|
98
|
+
## Commands
|
|
99
|
+
|
|
100
|
+
| Command | Purpose |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `cldc compile [repo]` | Parse sources, write `.claude/policy.lock.json`. |
|
|
103
|
+
| `cldc doctor [repo]` | Diagnose discovery, parsing, and lockfile state. |
|
|
104
|
+
| `cldc check [repo]` | Evaluate runtime evidence against the policy. |
|
|
105
|
+
| `cldc ci [repo]` | Same as `check`, but read changed files from `git diff`. |
|
|
106
|
+
| `cldc explain [repo]` | Render a saved or fresh report as text or markdown. |
|
|
107
|
+
| `cldc fix [repo]` | Build a deterministic remediation plan from a report. |
|
|
108
|
+
|
|
109
|
+
Every command takes `--json` and `--output <file>` for machine-readable, persistable results.
|
|
110
|
+
|
|
111
|
+
## Writing rules
|
|
112
|
+
|
|
113
|
+
Rules live inline in `CLAUDE.md`, in `.claude-compiler.yaml`, or in `policies/*.yml`. They merge in that order, deterministically.
|
|
114
|
+
|
|
115
|
+
````markdown
|
|
116
|
+
# CLAUDE.md
|
|
117
|
+
|
|
118
|
+
```cldc
|
|
119
|
+
rules:
|
|
120
|
+
- id: generated-lock
|
|
121
|
+
kind: deny_write
|
|
122
|
+
mode: block
|
|
123
|
+
paths: ["generated/**"]
|
|
124
|
+
message: Generated files are produced by the build — don't edit them.
|
|
125
|
+
```
|
|
126
|
+
````
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
# policies/commands.yml
|
|
130
|
+
rules:
|
|
131
|
+
- id: run-tests
|
|
132
|
+
kind: require_command
|
|
133
|
+
commands: ["pytest -q"]
|
|
134
|
+
when_paths: ["src/**", "tests/**"]
|
|
135
|
+
message: Run tests before finishing.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
| Kind | What it asserts |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `deny_write` | A path glob must not be written. |
|
|
141
|
+
| `require_read` | A path must be read before another path is written. |
|
|
142
|
+
| `require_command` | A command must run when matching paths are touched. |
|
|
143
|
+
| `couple_change` | Editing one path requires editing another. |
|
|
144
|
+
|
|
145
|
+
| Mode | Behavior |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `observe` | Recorded only. No exit-code change. |
|
|
148
|
+
| `warn` | Reported, exit `0`. *(default)* |
|
|
149
|
+
| `block` | Reported, exit `2`. |
|
|
150
|
+
| `fix` | Reported with a remediation plan from `cldc fix`. |
|
|
151
|
+
|
|
152
|
+
## Feeding evidence
|
|
153
|
+
|
|
154
|
+
`check`, `explain`, and `fix` accept evidence three ways. Mix and match.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Direct flags
|
|
158
|
+
cldc check . --read docs/spec.md --write src/main.py --command "pytest -q"
|
|
159
|
+
|
|
160
|
+
# JSON file (read_paths, write_paths, commands, claims, or events[])
|
|
161
|
+
cldc check . --events-file .cldc-events.json
|
|
162
|
+
|
|
163
|
+
# Stdin
|
|
164
|
+
cat .cldc-events.json | cldc check . --stdin-json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Save a report once, reuse it everywhere:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
cldc check . --events-file .cldc-events.json --json --output artifacts/report.json
|
|
171
|
+
cldc explain . --report-file artifacts/report.json --format markdown --output artifacts/report.md
|
|
172
|
+
cldc fix . --report-file artifacts/report.json --format markdown --output artifacts/fix.md
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## CI
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
# .github/workflows/policy.yml
|
|
179
|
+
name: policy
|
|
180
|
+
on: pull_request
|
|
181
|
+
|
|
182
|
+
jobs:
|
|
183
|
+
cldc:
|
|
184
|
+
runs-on: ubuntu-latest
|
|
185
|
+
steps:
|
|
186
|
+
- uses: actions/checkout@v4
|
|
187
|
+
with: { fetch-depth: 0 }
|
|
188
|
+
- uses: astral-sh/setup-uv@v6
|
|
189
|
+
- run: uv sync
|
|
190
|
+
- run: uv run cldc compile .
|
|
191
|
+
- name: Enforce
|
|
192
|
+
run: |
|
|
193
|
+
set +e
|
|
194
|
+
uv run cldc ci . \
|
|
195
|
+
--base origin/${{ github.base_ref }} --head ${{ github.sha }} \
|
|
196
|
+
--json --output artifacts/policy-report.json
|
|
197
|
+
status=$?
|
|
198
|
+
uv run cldc explain . \
|
|
199
|
+
--report-file artifacts/policy-report.json \
|
|
200
|
+
--format markdown --output artifacts/policy-explanation.md
|
|
201
|
+
exit $status
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`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.
|
|
205
|
+
|
|
206
|
+
## Develop
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
git clone https://github.com/AbdelStark/claude-md-compiler
|
|
210
|
+
cd claude-md-compiler
|
|
211
|
+
uv sync # creates .venv and installs cldc in editable mode
|
|
212
|
+
uv run pytest # full test suite
|
|
213
|
+
|
|
214
|
+
# Run the local build against a bundled fixture
|
|
215
|
+
uv run cldc compile tests/fixtures/repo_a
|
|
216
|
+
uv run cldc check tests/fixtures/repo_a \
|
|
217
|
+
--write src/main.py \
|
|
218
|
+
--read docs/rfcs/CLDC-0006-validator-engine.md \
|
|
219
|
+
--command "pytest -q"
|
|
220
|
+
|
|
221
|
+
# Or activate the venv and call cldc directly
|
|
222
|
+
source .venv/bin/activate
|
|
223
|
+
cldc --version
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`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/`.
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# claude-md-compiler
|
|
4
|
+
|
|
5
|
+
**Compile `CLAUDE.md` into a versioned lockfile. Enforce it on local edits, staged diffs, and CI.**
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/claude-md-compiler/)
|
|
8
|
+
[](https://www.python.org/)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
`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.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
`cldc` is a CLI you install once and point at any repo whose `CLAUDE.md` you want to enforce.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Persistent install (recommended)
|
|
23
|
+
uv tool install claude-md-compiler # or: pipx install claude-md-compiler
|
|
24
|
+
# or: pip install claude-md-compiler
|
|
25
|
+
|
|
26
|
+
# One-shot, no install
|
|
27
|
+
uvx --from claude-md-compiler cldc compile .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Verify with `cldc --version`. Requires Python 3.11+. The only runtime dependency is PyYAML.
|
|
31
|
+
|
|
32
|
+
> 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](#develop) workflow instead.
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 1. Compile policy from CLAUDE.md + policies/*.yml
|
|
38
|
+
cldc compile .
|
|
39
|
+
|
|
40
|
+
# 2. Check a change against it
|
|
41
|
+
cldc check . --write src/main.py --command "pytest -q"
|
|
42
|
+
|
|
43
|
+
# 3. Gate a pull request
|
|
44
|
+
cldc ci . --base origin/main --head HEAD
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Exit codes: `0` clean or warn-only · `1` runtime error · `2` blocking violations.
|
|
48
|
+
|
|
49
|
+
## How it works
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
sources evidence
|
|
53
|
+
───────────────────── ───────────────────────────
|
|
54
|
+
CLAUDE.md (cldc blocks) --read / --write / --command
|
|
55
|
+
.claude-compiler.yaml --events-file / --stdin-json
|
|
56
|
+
policies/*.yml git diff (staged | base..head)
|
|
57
|
+
│ │
|
|
58
|
+
▼ ▼
|
|
59
|
+
cldc compile cldc check / cldc ci
|
|
60
|
+
│ │
|
|
61
|
+
▼ ▼
|
|
62
|
+
.claude/policy.lock.json ───────────────▶ pass · warn · block
|
|
63
|
+
│
|
|
64
|
+
┌───────────┴───────────┐
|
|
65
|
+
▼ ▼
|
|
66
|
+
cldc explain cldc fix
|
|
67
|
+
(text · md · json) (remediation plan)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
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.
|
|
71
|
+
|
|
72
|
+
## Commands
|
|
73
|
+
|
|
74
|
+
| Command | Purpose |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `cldc compile [repo]` | Parse sources, write `.claude/policy.lock.json`. |
|
|
77
|
+
| `cldc doctor [repo]` | Diagnose discovery, parsing, and lockfile state. |
|
|
78
|
+
| `cldc check [repo]` | Evaluate runtime evidence against the policy. |
|
|
79
|
+
| `cldc ci [repo]` | Same as `check`, but read changed files from `git diff`. |
|
|
80
|
+
| `cldc explain [repo]` | Render a saved or fresh report as text or markdown. |
|
|
81
|
+
| `cldc fix [repo]` | Build a deterministic remediation plan from a report. |
|
|
82
|
+
|
|
83
|
+
Every command takes `--json` and `--output <file>` for machine-readable, persistable results.
|
|
84
|
+
|
|
85
|
+
## Writing rules
|
|
86
|
+
|
|
87
|
+
Rules live inline in `CLAUDE.md`, in `.claude-compiler.yaml`, or in `policies/*.yml`. They merge in that order, deterministically.
|
|
88
|
+
|
|
89
|
+
````markdown
|
|
90
|
+
# CLAUDE.md
|
|
91
|
+
|
|
92
|
+
```cldc
|
|
93
|
+
rules:
|
|
94
|
+
- id: generated-lock
|
|
95
|
+
kind: deny_write
|
|
96
|
+
mode: block
|
|
97
|
+
paths: ["generated/**"]
|
|
98
|
+
message: Generated files are produced by the build — don't edit them.
|
|
99
|
+
```
|
|
100
|
+
````
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
# policies/commands.yml
|
|
104
|
+
rules:
|
|
105
|
+
- id: run-tests
|
|
106
|
+
kind: require_command
|
|
107
|
+
commands: ["pytest -q"]
|
|
108
|
+
when_paths: ["src/**", "tests/**"]
|
|
109
|
+
message: Run tests before finishing.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
| Kind | What it asserts |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `deny_write` | A path glob must not be written. |
|
|
115
|
+
| `require_read` | A path must be read before another path is written. |
|
|
116
|
+
| `require_command` | A command must run when matching paths are touched. |
|
|
117
|
+
| `couple_change` | Editing one path requires editing another. |
|
|
118
|
+
|
|
119
|
+
| Mode | Behavior |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `observe` | Recorded only. No exit-code change. |
|
|
122
|
+
| `warn` | Reported, exit `0`. *(default)* |
|
|
123
|
+
| `block` | Reported, exit `2`. |
|
|
124
|
+
| `fix` | Reported with a remediation plan from `cldc fix`. |
|
|
125
|
+
|
|
126
|
+
## Feeding evidence
|
|
127
|
+
|
|
128
|
+
`check`, `explain`, and `fix` accept evidence three ways. Mix and match.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Direct flags
|
|
132
|
+
cldc check . --read docs/spec.md --write src/main.py --command "pytest -q"
|
|
133
|
+
|
|
134
|
+
# JSON file (read_paths, write_paths, commands, claims, or events[])
|
|
135
|
+
cldc check . --events-file .cldc-events.json
|
|
136
|
+
|
|
137
|
+
# Stdin
|
|
138
|
+
cat .cldc-events.json | cldc check . --stdin-json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Save a report once, reuse it everywhere:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cldc check . --events-file .cldc-events.json --json --output artifacts/report.json
|
|
145
|
+
cldc explain . --report-file artifacts/report.json --format markdown --output artifacts/report.md
|
|
146
|
+
cldc fix . --report-file artifacts/report.json --format markdown --output artifacts/fix.md
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## CI
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
# .github/workflows/policy.yml
|
|
153
|
+
name: policy
|
|
154
|
+
on: pull_request
|
|
155
|
+
|
|
156
|
+
jobs:
|
|
157
|
+
cldc:
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
steps:
|
|
160
|
+
- uses: actions/checkout@v4
|
|
161
|
+
with: { fetch-depth: 0 }
|
|
162
|
+
- uses: astral-sh/setup-uv@v6
|
|
163
|
+
- run: uv sync
|
|
164
|
+
- run: uv run cldc compile .
|
|
165
|
+
- name: Enforce
|
|
166
|
+
run: |
|
|
167
|
+
set +e
|
|
168
|
+
uv run cldc ci . \
|
|
169
|
+
--base origin/${{ github.base_ref }} --head ${{ github.sha }} \
|
|
170
|
+
--json --output artifacts/policy-report.json
|
|
171
|
+
status=$?
|
|
172
|
+
uv run cldc explain . \
|
|
173
|
+
--report-file artifacts/policy-report.json \
|
|
174
|
+
--format markdown --output artifacts/policy-explanation.md
|
|
175
|
+
exit $status
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`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.
|
|
179
|
+
|
|
180
|
+
## Develop
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
git clone https://github.com/AbdelStark/claude-md-compiler
|
|
184
|
+
cd claude-md-compiler
|
|
185
|
+
uv sync # creates .venv and installs cldc in editable mode
|
|
186
|
+
uv run pytest # full test suite
|
|
187
|
+
|
|
188
|
+
# Run the local build against a bundled fixture
|
|
189
|
+
uv run cldc compile tests/fixtures/repo_a
|
|
190
|
+
uv run cldc check tests/fixtures/repo_a \
|
|
191
|
+
--write src/main.py \
|
|
192
|
+
--read docs/rfcs/CLDC-0006-validator-engine.md \
|
|
193
|
+
--command "pytest -q"
|
|
194
|
+
|
|
195
|
+
# Or activate the venv and call cldc directly
|
|
196
|
+
source .venv/bin/activate
|
|
197
|
+
cldc --version
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`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/`.
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT — see [LICENSE](./LICENSE).
|