rulelab-cli 0.1.2__py3-none-any.whl

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.
@@ -0,0 +1,260 @@
1
+ Metadata-Version: 2.5
2
+ Name: rulelab-cli
3
+ Version: 0.1.2
4
+ Summary: Find out which lines of your AGENTS.md earn their tokens. Remove one rule at a time and measure success and cost on real tasks.
5
+ Project-URL: Homepage, https://diegoperezg7.github.io/rulelab/
6
+ Project-URL: Repository, https://github.com/diegoperezg7/rulelab
7
+ Project-URL: Issues, https://github.com/diegoperezg7/rulelab/issues
8
+ Author: Diego Pérez
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ablation,agents,agents-md,claude-md,coding-agents,evaluation,llm
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: commitarena==0.1.1
23
+ Requires-Dist: jinja2==3.1.6
24
+ Requires-Dist: rich==15.0.0
25
+ Requires-Dist: typer==0.27.3
26
+ Description-Content-Type: text/markdown
27
+
28
+ <p align="center">
29
+ <img src="docs/assets/banner.svg" alt="rulelab" width="560">
30
+ </p>
31
+
32
+ <p align="center">
33
+ <a href="https://github.com/diegoperezg7/rulelab/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/diegoperezg7/rulelab/actions/workflows/ci.yml/badge.svg"></a>
34
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-5d51d1"></a>
35
+ <a href="https://github.com/diegoperezg7/rulelab/releases"><img alt="Release" src="https://img.shields.io/github/v/release/diegoperezg7/rulelab?color=5d51d1"></a>
36
+ <a href="https://github.com/diegoperezg7/rulelab/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/diegoperezg7/rulelab?style=flat&color=5d51d1"></a>
37
+ </p>
38
+
39
+ <p align="center"><b>Find out which lines of your AGENTS.md earn their tokens.</b><br>
40
+ Remove one rule at a time and measure success and cost on real tasks.</p>
41
+
42
+ <p align="center"><a href="README.es.md">Leer en español</a> · <a href="https://diegoperezg7.github.io/rulelab/">Example report</a></p>
43
+
44
+ <p align="center"><img src="docs/assets/demo.gif" alt="rulelab split and rulelab demo in a terminal" width="820"></p>
45
+
46
+ <p align="center"><a href="https://diegoperezg7.github.io/rulelab/"><img src="docs/assets/report-light.png" alt="rulelab HTML report" width="820"></a></p>
47
+
48
+ ## Why
49
+
50
+ Every line in `AGENTS.md` or `CLAUDE.md` is sent to the model on every call. Is it worth it?
51
+
52
+ The best evidence so far says "often not". Gloaguen et al. (ETH Zurich and LogicStar.ai,
53
+ [arXiv 2602.11988](https://arxiv.org/abs/2602.11988)) ran Claude Code, Codex and Qwen Code on
54
+ SWE-bench Lite and on CTXbench (138 tasks from 12 repositories) and found that context files
55
+ **do not generally improve task success rates** while raising inference cost **by over 20% on
56
+ average**:
57
+
58
+ | Context file | Success | Inference cost |
59
+ | --- | --- | --- |
60
+ | Written by an LLM | −0.5% (SWE-bench Lite), −2% (CTXbench) | +20%, +23% |
61
+ | Written by developers | +2.4% (not significant) | up to +19% |
62
+
63
+ They also found that repository overviews do not help. That is the average over many repos.
64
+ Your file, your repo and your model are what matter to you, and the paper measures whole files,
65
+ not the individual rules you would actually delete.
66
+
67
+ rulelab runs that experiment on **your** repo, **one rule at a time**.
68
+
69
+ | | What it measures | Tasks |
70
+ | --- | --- | --- |
71
+ | [fernforge/ruleprof](https://github.com/fernforge/ruleprof) (0★) | Removes rules one at a time; checks whether the agent **obeys** each rule | Toy tasks |
72
+ | [sx4im/skillcheck](https://github.com/sx4im/skillcheck) (29★) | Blind A/B test of the **whole file** against no file | Your prompts |
73
+ | **rulelab** | Removes rules one at a time; measures **task success and cost** per rule | Real bug fixes from your repo's history, scored by its own tests |
74
+
75
+ Star counts checked with the GitHub API on 3 Nov 2026.
76
+
77
+ ## Quickstart
78
+
79
+ See a recorded real run (no API key, no Docker, under a minute):
80
+
81
+ ```bash
82
+ uvx rulelab-cli demo --open
83
+ ```
84
+
85
+ or from a clone:
86
+
87
+ ```bash
88
+ git clone https://github.com/diegoperezg7/rulelab && cd rulelab && uv run rulelab demo --open
89
+ ```
90
+
91
+ The PyPI package is `rulelab-cli` (the name `rulelab` is too close to an existing project there); the command is `rulelab`. Install it with `uv tool install rulelab-cli` or `pipx install rulelab-cli`.
92
+
93
+ Then run it on your own file and repo (needs Docker, and Ollama or an API key):
94
+
95
+ ```bash
96
+ rulelab split AGENTS.md # see how the file is split, free
97
+ rulelab run AGENTS.md --repo . --dry-run # plan and cost estimate, free
98
+ rulelab run AGENTS.md --repo . --model ollama/qwen3:4b # local model, 0 USD
99
+ rulelab run AGENTS.md --repo . --model mistral/ministral-14b-latest --price 0.2,0.2 -j 3
100
+ ```
101
+
102
+ ## Example output
103
+
104
+ ```text
105
+ $ rulelab demo
106
+ Recorded run · real results from rulelab run on 2026-11-03 · rulelab 0.1.0 · Darwin arm64 (Apple M4, 16 GB RAM)
107
+ AGENTS.md · model mistral/ministral-14b-latest · 4 tasks × 2 repeats × 8 configs · 64 runs · 0.7376 USD
108
+ full file 2/8 · no file 1/8 · file effect +12 pp [−21, +39]
109
+ file tokens per run, estimated if resent on every call: ≈4,305 · measured difference vs no file: +776 [−15,405, +17,616]
110
+ rule ≈tok effect (pp, 95% CI) verdict USD/month
111
+ R1 Repository overview 88 +12 [−21, +41] inconclusive 0.23
112
+ R2 Running tests 47 0 [−26, +25] inconclusive 0.12
113
+ R3 How to fix a bug 56 +12 [−20, +40] inconclusive 0.15
114
+ R4 Lexer and keywords 68 0 [−26, +27] inconclusive 0.18
115
+ R5 Code style 34 0 [−26, +27] inconclusive 0.09
116
+ R6 Communication 30 0 [−26, +26] inconclusive 0.08
117
+ Small sample: most rules are inconclusive. [...]
118
+ ```
119
+
120
+ **What this recorded run says, plainly.** The demo is a real `rulelab run` of a 6-rule
121
+ [AGENTS.md](examples/demo/AGENTS.md) (it includes a repository overview, as in the paper) on the 4
122
+ most recent tasks of commitarena's own demo set: bug fixes from
123
+ [sqlparse](https://github.com/andialbrecht/sqlparse), scored by sqlparse's tests
124
+ ([tasks.json](examples/demo/tasks.json)). Model `mistral/ministral-14b-latest`, 15 agent steps,
125
+ 2 repeats, commitarena 0.1.1: 64 agent runs, 27 minutes, 0.74 USD. The model was picked with a
126
+ 4-run probe because it passed some tasks but not all (1 of 4), so the baseline is neither 0% nor
127
+ 100% and an effect could show up.
128
+
129
+ 13 of 64 runs passed. The full file passed 2/8 and no file 1/8 (+12 pp, interval −21 to +39).
130
+ Removing the repository overview or the bug-fixing rule dropped success from 2/8 to 1/8, but with
131
+ 4 tasks and 2 repeats that is one run's difference: **every rule is inconclusive**, and the report
132
+ says so instead of forcing a verdict. What the run does pin down is the price: the file is ≈328
133
+ tokens; resent on each of ~13 model calls it would add an estimated ≈4,305 input tokens per run. The difference actually measured in this run (full file vs no file) was +776 input tokens per run, with a wide interval, because agent trajectories vary far more than that. To get a verdict,
134
+ run more tasks and repeats on your own repo.
135
+
136
+ An earlier, larger run (144 runs with codestral on an older commitarena build) solved 1 of 144
137
+ tasks and is not published as a result; it did prove that the run survives engine errors, budget
138
+ stops and interruptions (`--resume`).
139
+
140
+ The full report, with the annotated file, is published at
141
+ **[diegoperezg7.github.io/rulelab](https://diegoperezg7.github.io/rulelab/)** (EN/ES, light/dark).
142
+ Screenshots: [light](docs/assets/report-light.png) · [dark](docs/assets/report-dark.png) ·
143
+ [mobile](docs/assets/report-mobile.png).
144
+
145
+ ## How it works
146
+
147
+ ```mermaid
148
+ flowchart LR
149
+ F[AGENTS.md / CLAUDE.md] --> S[split into rules<br/>by section or bullet]
150
+ S --> C["configurations:<br/>no file · full file · full minus R1 … Rn"]
151
+ R[your repo] --> M[commitarena mine:<br/>real bug-fix commits with tests]
152
+ C --> X{{each config × each task × 3 repeats}}
153
+ M --> X
154
+ X --> D[Docker sandbox, no network:<br/>agent edits code, model called from host]
155
+ D --> T[repo's own tests decide pass/fail]
156
+ T --> B[bootstrap interval per rule:<br/>helps · no effect · hurts · inconclusive]
157
+ B --> H[HTML report + results.json]
158
+ ```
159
+
160
+ 1. **Split.** `--granularity section` (default) makes each heading a rule; `bullet` makes each
161
+ top-level bullet or paragraph a rule. A lone `# Title` line is kept in every configuration.
162
+ Check the split with `rulelab split`.
163
+ 2. **Configurations.** No file, the full file, and the full file without each rule
164
+ (leave-one-out). With *n* rules that is *n* + 2 configurations.
165
+ 3. **Tasks.** Real bug fixes from your git history, mined by
166
+ [commitarena](https://github.com/diegoperezg7/commitarena): commits that add a test that fails
167
+ before the fix. The agent gets the failing tests, never the commit message.
168
+ 4. **Runs.** Every configuration runs every task `--repeats` times (default 3) in the same
169
+ no-network Docker sandbox (2 CPU, 2 GB). The file is written at the repo root and appended to
170
+ the system prompt (`--inject both|repo|prompt`). The repo's own AGENTS.md/CLAUDE.md is removed
171
+ first, so "no file" really means none.
172
+ 5. **Verdict.** Effect of a rule = success with the full file − success without it. The 95%
173
+ interval comes from a two-level bootstrap (tasks resampled; each per-task rate drawn from a
174
+ Beta(s+½, f+½) posterior, so 3/3 vs 3/3 does not look like certainty). **Helps** if the whole
175
+ interval is above 0, **hurts** if below, **no effect** if it fits inside ±10 pp (`--margin`),
176
+ **inconclusive** otherwise.
177
+ 6. **Cost.** Tokens per rule (≈ characters / 4), the measured input-token difference per run, and
178
+ a monthly projection: rule tokens × model calls per run × sessions per month × input price.
179
+
180
+ ### Read the result honestly
181
+
182
+ With 6 tasks and 3 repeats, only large effects can be told apart from noise, so **most rules
183
+ will come out inconclusive**. The report says so in plain words instead of forcing a verdict.
184
+ "Inconclusive" is not "useless": it means this experiment cannot tell. Add tasks (`--max-tasks`)
185
+ or repeats before deleting a rule because of it.
186
+
187
+ ## Configuration
188
+
189
+ | Option | Default | What it does |
190
+ | --- | --- | --- |
191
+ | `--repo` | | Git repo (path or URL) to mine tasks from |
192
+ | `--tasks-file` | | Reuse a `tasks.json` from `commitarena mine` |
193
+ | `--only` | all | Comma-separated task ids |
194
+ | `--max-tasks` | 6 | Tasks to mine with `--repo` |
195
+ | `--model`, `-m` | `ollama/qwen3:4b` | `ollama/…`, `mistral/…`, `openrouter/…`, `openai/…` |
196
+ | `--granularity`, `-g` | `section` | `section` or `bullet` |
197
+ | `--repeats`, `-n` | 3 | Runs per task and configuration |
198
+ | `--max-cost` | 1.0 | Hard budget in USD, checked before every run. Local models count as 0 |
199
+ | `--inject` | `both` | Put the file in the repo root, the system prompt, or both |
200
+ | `--max-steps` | 30 | Model calls per run |
201
+ | `--concurrency`, `-j` | 1 | Agent runs at the same time, each in its own sandbox |
202
+ | `--price` | | `IN,OUT` USD per 1M tokens for models without a known price |
203
+ | `--price-source` | | Where that price comes from; shown in the report |
204
+ | `--sessions-per-month` | 1000 | For the monthly cost projection |
205
+ | `--out`, `-o` | `rulelab-results` | Writes `results.json` (after every run) and `report.html` |
206
+ | `--resume` | | Continue an interrupted or budget-stopped run |
207
+ | `--dry-run` | | Print the plan and estimate only |
208
+
209
+ Before anything runs, rulelab prints the number of agent runs and the estimated cost. If the
210
+ estimate is over `--max-cost`, it stops and tells you the amount to pass instead. Nothing is spent
211
+ until you allow it.
212
+
213
+ **Small local models.** Ollama serves models with a 4,096-token context by default. An agent run
214
+ needs far more, and in our test `qwen3:4b` used up that window thinking and never ran a command.
215
+ Start Ollama with a bigger window (for example `OLLAMA_CONTEXT_LENGTH=32768 ollama serve`) before
216
+ using a local model.
217
+
218
+ **Keys** come only from environment variables: `MISTRAL_API_KEY`, `OPENROUTER_API_KEY`,
219
+ `OPENAI_API_KEY` (see [.env.example](.env.example)). Ollama needs none (`OLLAMA_HOST` to point
220
+ elsewhere). rulelab sends no telemetry.
221
+
222
+ `rulelab report results.json` rebuilds the report with another `--margin`, `--price-in` or
223
+ `--sessions-per-month` without re-running anything.
224
+
225
+ ## Use it from Claude Code
226
+
227
+ Install the plugin and ask Claude in plain words; its `ablate-agent-rules` skill splits your file, shows the free cost estimate, runs the experiment only after you approve it and explains which rules help, hurt or cannot be told apart yet.
228
+
229
+ ```text
230
+ /plugin install rulelab --marketplace diegoperezg7/rulelab
231
+ ```
232
+
233
+ The skill tells Claude to ask before any paid run, and `--max-cost` still caps the spend.
234
+
235
+ ## Roadmap
236
+
237
+ Not in v0.1:
238
+
239
+ - Synthetic tasks for repos without enough bug-fix history.
240
+ - Adherence checks (did the agent follow the rule?), as a second signal next to success.
241
+ - `.cursor/rules` and skills.
242
+ - Rule interactions (removing pairs or groups).
243
+ - Automatic rewrites of rules that cost more than they help.
244
+
245
+ ## Part of a series
246
+
247
+ Open source tools that evaluate agents and LLMs on your own data:
248
+
249
+ - [memarena](https://github.com/diegoperezg7/memarena): Benchmark memory layers on your own conversations.
250
+ - [parsearena](https://github.com/diegoperezg7/parsearena): Compare PDF parsers side by side and their effect on retrieval.
251
+ - [commitarena](https://github.com/diegoperezg7/commitarena): Replay real bug fixes from your git history against any model.
252
+ - [toolbloat](https://github.com/diegoperezg7/toolbloat): Measure the token cost of your MCP stack and tool-choice errors.
253
+ - [doesitfire](https://github.com/diegoperezg7/doesitfire): Test whether your SKILL.md activates in Claude Code, Codex and OpenCode.
254
+
255
+ ## License
256
+
257
+ [MIT](LICENSE) © 2026 Diego Pérez. The demo tasks contain code and tests from
258
+ [andialbrecht/sqlparse](https://github.com/andialbrecht/sqlparse) (BSD-3-Clause, see
259
+ [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)), taken from commitarena's demo set; the demo
260
+ AGENTS.md in [`examples/demo`](examples/demo) was written for this project.
@@ -0,0 +1,19 @@
1
+ rulelab/__init__.py,sha256=9klZUewpMicT37wmf0d7K4F4LQvqG1Q1J--O0vxDTYg,107
2
+ rulelab/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
3
+ rulelab/analysis.py,sha256=xuje2fOyGyxQMERsodFkjYsWYKFFWqUHBs2pbgvGYeA,6023
4
+ rulelab/cli.py,sha256=CTVIch0zR_WohsvELyBAj2xeVmDHleH_7BywcFoya00,15541
5
+ rulelab/configs.py,sha256=exmWlY_5IUYiWvTmwJIU8E05B1J3CA1V0ux98_wZxaQ,1085
6
+ rulelab/engine.py,sha256=mao6J_mite5w8j9akkyGs-u12E3uXFq6_US86LuW8s4,10534
7
+ rulelab/errors.py,sha256=ja_LZn1weNTTtrcTSYqfNW7ftRU6weADo9OFk-OVJ-w,286
8
+ rulelab/experiment.py,sha256=b0wNRGpuUTMU54pd_YEz0UOZxXsg2BSMSk0IbZ181oQ,7334
9
+ rulelab/report.py,sha256=6ETb1ZqQsRYokSr8KSy8rHDEZ9_ecnWE9RuuuUHvOes,6424
10
+ rulelab/rules.py,sha256=Nr2z6L_2-L6NvdVZmhZqJb4tbA7mwf8scOM68wtgXXY,7880
11
+ rulelab/runner.py,sha256=DOdWidyILYhVwYsJrrEQvJhRTWJnsSB-_GnUnM9z53o,2956
12
+ rulelab/stats.py,sha256=VVafswKitbhSxufxE5rDEeMiU59B6kP8LWCCTZGZWKg,5699
13
+ rulelab/templates/report.html.j2,sha256=Jh7UvKT6jYD-72v2ZUPWuuflGlUhbTiYnBQOBWSa8VE,28391
14
+ rulelab/_demo/results.json,sha256=jGAKVZCksgf9vm-d58FWpJrBBDsxfcv0jEy25Zcf1uw,23489
15
+ rulelab_cli-0.1.2.dist-info/METADATA,sha256=sW2inAh5EcbNpJAUeW8LXqz5ysgSIipByHom6BTBGF0,14368
16
+ rulelab_cli-0.1.2.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
17
+ rulelab_cli-0.1.2.dist-info/entry_points.txt,sha256=J-4SVUGtPyTPsfyoJJ_vRF_F4uynzPrQhGLhcYnfVFc,76
18
+ rulelab_cli-0.1.2.dist-info/licenses/LICENSE,sha256=A7Jh3ub2oGhc2l6P9raz5AeuQKzRIinCPYAXENE2Lig,1069
19
+ rulelab_cli-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ rulelab = rulelab.cli:main
3
+ rulelab-cli = rulelab.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Diego Pérez
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.