rulelab-cli 0.1.2__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.
- rulelab_cli-0.1.2/.gitignore +12 -0
- rulelab_cli-0.1.2/CHANGELOG.md +42 -0
- rulelab_cli-0.1.2/LICENSE +21 -0
- rulelab_cli-0.1.2/PKG-INFO +260 -0
- rulelab_cli-0.1.2/README.es.md +235 -0
- rulelab_cli-0.1.2/README.md +233 -0
- rulelab_cli-0.1.2/THIRD_PARTY_NOTICES.md +35 -0
- rulelab_cli-0.1.2/examples/demo/AGENTS.md +35 -0
- rulelab_cli-0.1.2/examples/demo/results.json +956 -0
- rulelab_cli-0.1.2/examples/demo/tasks.json +5603 -0
- rulelab_cli-0.1.2/plugin/README.md +22 -0
- rulelab_cli-0.1.2/pyproject.toml +59 -0
- rulelab_cli-0.1.2/src/rulelab/__init__.py +3 -0
- rulelab_cli-0.1.2/src/rulelab/__main__.py +3 -0
- rulelab_cli-0.1.2/src/rulelab/analysis.py +174 -0
- rulelab_cli-0.1.2/src/rulelab/cli.py +344 -0
- rulelab_cli-0.1.2/src/rulelab/configs.py +39 -0
- rulelab_cli-0.1.2/src/rulelab/engine.py +272 -0
- rulelab_cli-0.1.2/src/rulelab/errors.py +9 -0
- rulelab_cli-0.1.2/src/rulelab/experiment.py +195 -0
- rulelab_cli-0.1.2/src/rulelab/report.py +205 -0
- rulelab_cli-0.1.2/src/rulelab/rules.py +225 -0
- rulelab_cli-0.1.2/src/rulelab/runner.py +94 -0
- rulelab_cli-0.1.2/src/rulelab/stats.py +180 -0
- rulelab_cli-0.1.2/src/rulelab/templates/report.html.j2 +379 -0
- rulelab_cli-0.1.2/tests/conftest.py +14 -0
- rulelab_cli-0.1.2/tests/fixtures/sample_agents.md +27 -0
- rulelab_cli-0.1.2/tests/test_cli.py +101 -0
- rulelab_cli-0.1.2/tests/test_docker.py +11 -0
- rulelab_cli-0.1.2/tests/test_engine.py +91 -0
- rulelab_cli-0.1.2/tests/test_experiment.py +124 -0
- rulelab_cli-0.1.2/tests/test_rules.py +74 -0
- rulelab_cli-0.1.2/tests/test_stats.py +68 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.2] - 2026-11-04
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Published on PyPI as `rulelab-cli` (the name `rulelab` is too close to an existing project). The command is still `rulelab`; `rulelab-cli` works too, so `uvx rulelab-cli` runs it.
|
|
11
|
+
- Depends on `commitarena==0.1.1` from PyPI instead of its GitHub tag.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Claude Code plugin (`/plugin install rulelab --marketplace diegoperezg7/rulelab`) with the `ablate-agent-rules` skill.
|
|
15
|
+
|
|
16
|
+
## [0.1.1] - 2026-11-03
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- Report: numbers follow the active language (ES `1.953`, `0,23 US$`; EN `1,953`, `0.23 USD`).
|
|
20
|
+
- Report: the cost-projection footnote is fully translated.
|
|
21
|
+
- Report, terminal summary and docs: the estimated tokens per run (file resent on every call) and the measured
|
|
22
|
+
difference against no file are shown as two separate, named figures.
|
|
23
|
+
|
|
24
|
+
## [0.1.0] - 2026-11-03
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- `rulelab split`: split AGENTS.md / CLAUDE.md into rules by section or by bullet.
|
|
28
|
+
- `rulelab run`: leave-one-out experiment (no file, full file, full file minus each rule) on real
|
|
29
|
+
tasks mined from a repository's history, through the commitarena engine (no-network Docker
|
|
30
|
+
sandbox), 3 repeats by default.
|
|
31
|
+
- Per-rule verdict (helps / no effect / hurts / inconclusive) from a two-level bootstrap interval,
|
|
32
|
+
tokens per rule and projected monthly cost.
|
|
33
|
+
- Plan and cost estimate before running; `--max-cost` (default 1 USD) checked before every run,
|
|
34
|
+
partial results kept, `--resume` to continue.
|
|
35
|
+
- Static HTML report (EN/ES, light/dark, mobile) with the annotated file.
|
|
36
|
+
- `--concurrency` to run several agent attempts at once (each in its own sandbox).
|
|
37
|
+
- `rulelab demo`: a recorded real run on 4 tasks of the commitarena demo set (ministral-14b, 64 runs).
|
|
38
|
+
|
|
39
|
+
### Notes
|
|
40
|
+
- rulelab depends on `commitarena` from its GitHub tag (`v0.1.1`). PyPI rejects direct URL
|
|
41
|
+
dependencies, so that dependency moves to the PyPI release once commitarena is published there,
|
|
42
|
+
and rulelab is published to PyPI after that.
|
|
@@ -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.
|
|
@@ -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,235 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/banner.svg" alt="rulelab" width="560">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<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>
|
|
7
|
+
<a href="LICENSE"><img alt="Licencia: MIT" src="https://img.shields.io/badge/license-MIT-5d51d1"></a>
|
|
8
|
+
<a href="https://github.com/diegoperezg7/rulelab/releases"><img alt="Release" src="https://img.shields.io/github/v/release/diegoperezg7/rulelab?color=5d51d1"></a>
|
|
9
|
+
<a href="https://github.com/diegoperezg7/rulelab/stargazers"><img alt="Estrellas" src="https://img.shields.io/github/stars/diegoperezg7/rulelab?style=flat&color=5d51d1"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><b>Descubre qué líneas de tu AGENTS.md se ganan sus tokens.</b><br>
|
|
13
|
+
Quita una regla cada vez y mide acierto y coste en tareas reales.</p>
|
|
14
|
+
|
|
15
|
+
<p align="center"><a href="README.md">Read in English</a> · <a href="https://diegoperezg7.github.io/rulelab/">Informe de ejemplo</a></p>
|
|
16
|
+
|
|
17
|
+
<p align="center"><img src="docs/assets/demo.gif" alt="rulelab split y rulelab demo en un terminal" width="820"></p>
|
|
18
|
+
|
|
19
|
+
<p align="center"><a href="https://diegoperezg7.github.io/rulelab/"><img src="docs/assets/report-light.png" alt="Informe HTML de rulelab" width="820"></a></p>
|
|
20
|
+
|
|
21
|
+
## Por qué
|
|
22
|
+
|
|
23
|
+
Cada línea de `AGENTS.md` o `CLAUDE.md` se envía al modelo en cada llamada. ¿Merece la pena?
|
|
24
|
+
|
|
25
|
+
La mejor evidencia hasta ahora dice que a menudo no. Gloaguen et al. (ETH Zúrich y LogicStar.ai,
|
|
26
|
+
[arXiv 2602.11988](https://arxiv.org/abs/2602.11988)) pusieron a Claude Code, Codex y Qwen Code
|
|
27
|
+
sobre SWE-bench Lite y CTXbench (138 tareas de 12 repositorios) y vieron que los ficheros de
|
|
28
|
+
contexto **no mejoran en general el acierto** y suben el coste de inferencia **más de un 20 % de
|
|
29
|
+
media**:
|
|
30
|
+
|
|
31
|
+
| Fichero de contexto | Acierto | Coste de inferencia |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Escrito por un LLM | −0,5 % (SWE-bench Lite), −2 % (CTXbench) | +20 %, +23 % |
|
|
34
|
+
| Escrito por desarrolladores | +2,4 % (no significativo) | hasta +19 % |
|
|
35
|
+
|
|
36
|
+
También vieron que las descripciones generales del repositorio no ayudan. Eso es la media de
|
|
37
|
+
muchos repos. A ti te importan tu fichero, tu repo y tu modelo, y el paper mide ficheros
|
|
38
|
+
enteros, no las reglas sueltas que de verdad borrarías.
|
|
39
|
+
|
|
40
|
+
rulelab hace ese experimento sobre **tu** repo, **regla a regla**.
|
|
41
|
+
|
|
42
|
+
| | Qué mide | Tareas |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| [fernforge/ruleprof](https://github.com/fernforge/ruleprof) (0★) | Quita reglas de una en una y mira si el agente **obedece** cada regla | De juguete |
|
|
45
|
+
| [sx4im/skillcheck](https://github.com/sx4im/skillcheck) (29★) | A/B a ciegas del **fichero entero** frente a no tenerlo | Tus prompts |
|
|
46
|
+
| **rulelab** | Quita reglas de una en una y mide **acierto y coste** por regla | Arreglos reales del historial de tu repo, puntuados con sus propios tests |
|
|
47
|
+
|
|
48
|
+
Estrellas comprobadas con la API de GitHub el 3 nov 2026.
|
|
49
|
+
|
|
50
|
+
## Inicio rápido
|
|
51
|
+
|
|
52
|
+
Mira una ejecución real grabada (sin API key, sin Docker, en menos de un minuto):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uvx rulelab-cli demo --open
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
o desde un clon:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/diegoperezg7/rulelab && cd rulelab && uv run rulelab demo --open
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
En PyPI el paquete se llama `rulelab-cli` (el nombre `rulelab` se parece demasiado a un proyecto que ya existe allí); el comando es `rulelab`. Instálalo con `uv tool install rulelab-cli` o `pipx install rulelab-cli`.
|
|
65
|
+
|
|
66
|
+
Después, sobre tu propio fichero y repo (necesita Docker, y Ollama o una API key):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
rulelab split AGENTS.md # cómo se parte el fichero, gratis
|
|
70
|
+
rulelab run AGENTS.md --repo . --dry-run # plan y coste estimado, gratis
|
|
71
|
+
rulelab run AGENTS.md --repo . --model ollama/qwen3:4b # modelo local, 0 USD
|
|
72
|
+
rulelab run AGENTS.md --repo . --model mistral/ministral-14b-latest --price 0.2,0.2 -j 3
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Salida de ejemplo
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
$ rulelab demo
|
|
79
|
+
Recorded run · real results from rulelab run on 2026-11-03 · rulelab 0.1.0 · Darwin arm64 (Apple M4, 16 GB RAM)
|
|
80
|
+
AGENTS.md · model mistral/ministral-14b-latest · 4 tasks × 2 repeats × 8 configs · 64 runs · 0.7376 USD
|
|
81
|
+
full file 2/8 · no file 1/8 · file effect +12 pp [−21, +39]
|
|
82
|
+
file tokens per run, estimated if resent on every call: ≈4,305 · measured difference vs no file: +776 [−15,405, +17,616]
|
|
83
|
+
rule ≈tok effect (pp, 95% CI) verdict USD/month
|
|
84
|
+
R1 Repository overview 88 +12 [−21, +41] inconclusive 0.23
|
|
85
|
+
R2 Running tests 47 0 [−26, +25] inconclusive 0.12
|
|
86
|
+
R3 How to fix a bug 56 +12 [−20, +40] inconclusive 0.15
|
|
87
|
+
R4 Lexer and keywords 68 0 [−26, +27] inconclusive 0.18
|
|
88
|
+
R5 Code style 34 0 [−26, +27] inconclusive 0.09
|
|
89
|
+
R6 Communication 30 0 [−26, +26] inconclusive 0.08
|
|
90
|
+
Small sample: most rules are inconclusive. [...]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Lo que dice esta ejecución grabada, sin adornos.** La demo es un `rulelab run` real de un
|
|
94
|
+
[AGENTS.md](examples/demo/AGENTS.md) de 6 reglas (incluye una descripción general del repositorio,
|
|
95
|
+
como en el paper) sobre las 4 tareas más recientes de la demo de commitarena: arreglos de bugs de
|
|
96
|
+
[sqlparse](https://github.com/andialbrecht/sqlparse), puntuados con los tests de sqlparse
|
|
97
|
+
([tasks.json](examples/demo/tasks.json)). Modelo `mistral/ministral-14b-latest`, 15 pasos de agente,
|
|
98
|
+
2 repeticiones, commitarena 0.1.1: 64 ejecuciones, 27 minutos, 0,74 USD. El modelo se eligió con
|
|
99
|
+
un sondeo de 4 ejecuciones porque resolvía algunas tareas pero no todas (1 de 4), así que la línea
|
|
100
|
+
base no es ni 0 % ni 100 % y un efecto podría aparecer.
|
|
101
|
+
|
|
102
|
+
Pasaron 13 de 64 ejecuciones. El fichero completo pasó 2/8 y sin fichero 1/8 (+12 pp, intervalo de
|
|
103
|
+
−21 a +39). Quitar la descripción del repositorio o la regla de cómo arreglar un bug bajó el
|
|
104
|
+
acierto de 2/8 a 1/8, pero con 4 tareas y 2 repeticiones eso es una sola ejecución de diferencia:
|
|
105
|
+
**todas las reglas salen no concluyentes**, y el informe lo dice en vez de forzar un veredicto. Lo
|
|
106
|
+
que sí deja claro es el precio: el fichero son ≈328 tokens reenviados en cada una de las ~13
|
|
107
|
+
llamadas al modelo; reenviado en cada una sumaría ≈4.305 tokens de entrada por ejecución estimados. La diferencia medida de verdad en esta ejecución (fichero completo frente a sin fichero) fue de +776 tokens de entrada por ejecución, con un intervalo amplio, porque las trayectorias del agente varían mucho más que eso. Para tener un veredicto, usa más
|
|
108
|
+
tareas y repeticiones sobre tu propio repo.
|
|
109
|
+
|
|
110
|
+
Una ejecución anterior más grande (144 ejecuciones con codestral sobre una versión previa de
|
|
111
|
+
commitarena) resolvió 1 de 144 tareas y no se publica como resultado; sí demostró que la ejecución
|
|
112
|
+
sobrevive a errores del motor, cortes por presupuesto e interrupciones (`--resume`).
|
|
113
|
+
|
|
114
|
+
El informe completo, con el fichero anotado, está publicado en
|
|
115
|
+
**[diegoperezg7.github.io/rulelab](https://diegoperezg7.github.io/rulelab/)** (EN/ES, claro/oscuro).
|
|
116
|
+
Capturas: [claro](docs/assets/report-light.png) · [oscuro](docs/assets/report-dark.png) ·
|
|
117
|
+
[móvil](docs/assets/report-mobile.png).
|
|
118
|
+
|
|
119
|
+
## Cómo funciona
|
|
120
|
+
|
|
121
|
+
```mermaid
|
|
122
|
+
flowchart LR
|
|
123
|
+
F[AGENTS.md / CLAUDE.md] --> S[partir en reglas<br/>por sección o viñeta]
|
|
124
|
+
S --> C["configuraciones:<br/>sin fichero · completo · completo sin R1 … Rn"]
|
|
125
|
+
R[tu repo] --> M[commitarena mine:<br/>commits reales que arreglan un bug con test]
|
|
126
|
+
C --> X{{cada config × cada tarea × 3 repeticiones}}
|
|
127
|
+
M --> X
|
|
128
|
+
X --> D[sandbox Docker sin red:<br/>el agente edita código, el modelo se llama desde el host]
|
|
129
|
+
D --> T[los tests del repo deciden si pasa]
|
|
130
|
+
T --> B[intervalo bootstrap por regla:<br/>ayuda · sin efecto · empeora · no concluyente]
|
|
131
|
+
B --> H[informe HTML + results.json]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
1. **Partir.** `--granularity section` (por defecto) convierte cada encabezado en una regla;
|
|
135
|
+
`bullet`, cada viñeta de primer nivel o párrafo. Un `# Título` suelto se mantiene en todas las
|
|
136
|
+
configuraciones. Compruébalo con `rulelab split`.
|
|
137
|
+
2. **Configuraciones.** Sin fichero, fichero completo y fichero completo sin cada regla. Con
|
|
138
|
+
*n* reglas son *n* + 2 configuraciones.
|
|
139
|
+
3. **Tareas.** Arreglos de bugs reales de tu historial de git, minados por
|
|
140
|
+
[commitarena](https://github.com/diegoperezg7/commitarena): commits que añaden un test que falla
|
|
141
|
+
antes del arreglo. El agente recibe los tests que fallan, nunca el mensaje del commit.
|
|
142
|
+
4. **Ejecuciones.** Cada configuración corre cada tarea `--repeats` veces (3 por defecto) en el
|
|
143
|
+
mismo sandbox Docker sin red (2 CPU, 2 GB). El fichero se escribe en la raíz del repo y se añade
|
|
144
|
+
al prompt de sistema (`--inject both|repo|prompt`). Antes se quita el AGENTS.md/CLAUDE.md propio
|
|
145
|
+
del repo, así que «sin fichero» es sin fichero de verdad.
|
|
146
|
+
5. **Veredicto.** Efecto de una regla = acierto con el fichero completo − acierto sin ella. El
|
|
147
|
+
intervalo del 95 % sale de un bootstrap en dos niveles (se remuestrean tareas y el acierto por
|
|
148
|
+
tarea se saca de una posterior Beta(s+½, f+½), para que 3/3 frente a 3/3 no parezca una
|
|
149
|
+
certeza). **Ayuda** si todo el intervalo está por encima de 0, **empeora** si está por debajo,
|
|
150
|
+
**sin efecto** si cabe dentro de ±10 pp (`--margin`) y **no concluyente** en otro caso.
|
|
151
|
+
6. **Coste.** Tokens por regla (≈ caracteres / 4), la diferencia medida de tokens de entrada por
|
|
152
|
+
ejecución y una proyección mensual: tokens de la regla × llamadas al modelo por ejecución ×
|
|
153
|
+
sesiones al mes × precio de entrada.
|
|
154
|
+
|
|
155
|
+
### Leer el resultado con honestidad
|
|
156
|
+
|
|
157
|
+
Con 6 tareas y 3 repeticiones solo se distinguen del ruido los efectos grandes, así que **la
|
|
158
|
+
mayoría de reglas saldrán no concluyentes**. El informe lo dice tal cual en vez de forzar un
|
|
159
|
+
veredicto. «No concluyente» no es «inútil»: significa que este experimento no puede decidirlo.
|
|
160
|
+
Añade tareas (`--max-tasks`) o repeticiones antes de borrar una regla por eso.
|
|
161
|
+
|
|
162
|
+
## Configuración
|
|
163
|
+
|
|
164
|
+
| Opción | Por defecto | Qué hace |
|
|
165
|
+
| --- | --- | --- |
|
|
166
|
+
| `--repo` | | Repo git (ruta o URL) del que minar tareas |
|
|
167
|
+
| `--tasks-file` | | Reusar un `tasks.json` de `commitarena mine` |
|
|
168
|
+
| `--only` | todas | Ids de tarea separados por comas |
|
|
169
|
+
| `--max-tasks` | 6 | Tareas a minar con `--repo` |
|
|
170
|
+
| `--model`, `-m` | `ollama/qwen3:4b` | `ollama/…`, `mistral/…`, `openrouter/…`, `openai/…` |
|
|
171
|
+
| `--granularity`, `-g` | `section` | `section` o `bullet` |
|
|
172
|
+
| `--repeats`, `-n` | 3 | Ejecuciones por tarea y configuración |
|
|
173
|
+
| `--max-cost` | 1.0 | Tope de gasto en USD, comprobado antes de cada ejecución. Los modelos locales cuentan 0 |
|
|
174
|
+
| `--inject` | `both` | El fichero en la raíz del repo, en el prompt de sistema o en ambos |
|
|
175
|
+
| `--max-steps` | 30 | Llamadas al modelo por ejecución |
|
|
176
|
+
| `--concurrency`, `-j` | 1 | Ejecuciones a la vez, cada una en su sandbox |
|
|
177
|
+
| `--price` | | `IN,OUT` en USD por 1M de tokens para modelos sin precio conocido |
|
|
178
|
+
| `--price-source` | | De dónde sale ese precio; aparece en el informe |
|
|
179
|
+
| `--sessions-per-month` | 1000 | Para la proyección de coste mensual |
|
|
180
|
+
| `--out`, `-o` | `rulelab-results` | Escribe `results.json` (tras cada ejecución) y `report.html` |
|
|
181
|
+
| `--resume` | | Continuar una ejecución interrumpida o parada por presupuesto |
|
|
182
|
+
| `--dry-run` | | Solo imprime el plan y la estimación |
|
|
183
|
+
|
|
184
|
+
Antes de ejecutar nada, rulelab imprime el número de ejecuciones del agente y el coste estimado.
|
|
185
|
+
Si la estimación supera `--max-cost`, se para y te dice qué cantidad pasar. No se gasta nada
|
|
186
|
+
hasta que lo permites.
|
|
187
|
+
|
|
188
|
+
**Modelos locales pequeños.** Ollama sirve los modelos con un contexto de 4.096 tokens por
|
|
189
|
+
defecto. Una ejecución del agente necesita mucho más, y en nuestra prueba `qwen3:4b` gastó esa
|
|
190
|
+
ventana pensando y nunca llegó a ejecutar un comando. Arranca Ollama con una ventana mayor (por
|
|
191
|
+
ejemplo `OLLAMA_CONTEXT_LENGTH=32768 ollama serve`) antes de usar un modelo local.
|
|
192
|
+
|
|
193
|
+
**Las claves** se leen solo de variables de entorno: `MISTRAL_API_KEY`, `OPENROUTER_API_KEY`,
|
|
194
|
+
`OPENAI_API_KEY` (ver [.env.example](.env.example)). Ollama no necesita ninguna (`OLLAMA_HOST`
|
|
195
|
+
para apuntar a otro sitio). rulelab no envía telemetría.
|
|
196
|
+
|
|
197
|
+
`rulelab report results.json` regenera el informe con otro `--margin`, `--price-in` o
|
|
198
|
+
`--sessions-per-month` sin volver a ejecutar nada.
|
|
199
|
+
|
|
200
|
+
## Úsalo desde Claude Code
|
|
201
|
+
|
|
202
|
+
Instala el plugin y pídeselo a Claude con tus palabras; su skill `ablate-agent-rules` divide tu fichero, enseña la estimación de coste (gratis), lanza el experimento solo cuando lo apruebas y explica qué reglas ayudan, cuáles perjudican y cuáles aún no se pueden distinguir.
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
/plugin install rulelab --marketplace diegoperezg7/rulelab
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
La skill indica a Claude que pregunte antes de cualquier ejecución de pago, y `--max-cost` sigue limitando el gasto.
|
|
209
|
+
|
|
210
|
+
## Hoja de ruta
|
|
211
|
+
|
|
212
|
+
Fuera de la v0.1:
|
|
213
|
+
|
|
214
|
+
- Tareas sintéticas para repos sin suficiente historial de arreglos.
|
|
215
|
+
- Comprobación de obediencia (¿siguió el agente la regla?) como segunda señal junto al acierto.
|
|
216
|
+
- `.cursor/rules` y skills.
|
|
217
|
+
- Interacciones entre reglas (quitar parejas o grupos).
|
|
218
|
+
- Reescritura automática de reglas que cuestan más de lo que ayudan.
|
|
219
|
+
|
|
220
|
+
## Parte de una serie
|
|
221
|
+
|
|
222
|
+
Herramientas open source para medir agentes y LLMs con tus propios datos:
|
|
223
|
+
|
|
224
|
+
- [memarena](https://github.com/diegoperezg7/memarena): Compara capas de memoria con tus propias conversaciones.
|
|
225
|
+
- [parsearena](https://github.com/diegoperezg7/parsearena): Compara parsers de PDF lado a lado y su efecto en la recuperación.
|
|
226
|
+
- [commitarena](https://github.com/diegoperezg7/commitarena): Reproduce fixes reales de tu historial de git con cualquier modelo.
|
|
227
|
+
- [toolbloat](https://github.com/diegoperezg7/toolbloat): Mide el coste en tokens de tu pila MCP y los errores al elegir tool.
|
|
228
|
+
- [doesitfire](https://github.com/diegoperezg7/doesitfire): Comprueba si tu SKILL.md se activa en Claude Code, Codex y OpenCode.
|
|
229
|
+
|
|
230
|
+
## Licencia
|
|
231
|
+
|
|
232
|
+
[MIT](LICENSE) © 2026 Diego Pérez. Las tareas de la demo contienen código y tests de
|
|
233
|
+
[andialbrecht/sqlparse](https://github.com/andialbrecht/sqlparse) (BSD-3-Clause, ver
|
|
234
|
+
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)), tomadas de la demo de commitarena; el AGENTS.md
|
|
235
|
+
de la demo en [`examples/demo`](examples/demo) se escribió para este proyecto.
|