rein-agentic-kit 0.7.1__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.
- rein_agentic_kit-0.7.1/LICENSE +21 -0
- rein_agentic_kit-0.7.1/PKG-INFO +340 -0
- rein_agentic_kit-0.7.1/README.md +320 -0
- rein_agentic_kit-0.7.1/plugins/rein/.claude-plugin/plugin.json +19 -0
- rein_agentic_kit-0.7.1/plugins/rein/__init__.py +0 -0
- rein_agentic_kit-0.7.1/plugins/rein/_entry.py +39 -0
- rein_agentic_kit-0.7.1/plugins/rein/bin/rein +716 -0
- rein_agentic_kit-0.7.1/plugins/rein/commands/ping.md +35 -0
- rein_agentic_kit-0.7.1/plugins/rein/commands/setup.md +34 -0
- rein_agentic_kit-0.7.1/plugins/rein/flow.config.example.json +59 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/dashboard.py +1311 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/detect.py +885 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/events.py +149 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/gate.py +283 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/plan.py +348 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/plan_check.py +219 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/serve.py +413 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/setup.py +455 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/token_report.py +716 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/verify.py +412 -0
- rein_agentic_kit-0.7.1/plugins/rein/lib/version_staleness.py +330 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/loop/SKILL.md +96 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/plan/SKILL.md +166 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/review/SKILL.md +107 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/role/SKILL.md +78 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/run/SKILL.md +59 -0
- rein_agentic_kit-0.7.1/plugins/rein/skills/run-auto/SKILL.md +70 -0
- rein_agentic_kit-0.7.1/plugins/rein/workflows/loop.js +2335 -0
- rein_agentic_kit-0.7.1/pyproject.toml +53 -0
- rein_agentic_kit-0.7.1/rein_agentic_kit.egg-info/PKG-INFO +340 -0
- rein_agentic_kit-0.7.1/rein_agentic_kit.egg-info/SOURCES.txt +66 -0
- rein_agentic_kit-0.7.1/rein_agentic_kit.egg-info/dependency_links.txt +1 -0
- rein_agentic_kit-0.7.1/rein_agentic_kit.egg-info/entry_points.txt +2 -0
- rein_agentic_kit-0.7.1/rein_agentic_kit.egg-info/top_level.txt +1 -0
- rein_agentic_kit-0.7.1/setup.cfg +4 -0
- rein_agentic_kit-0.7.1/tests/test_baseline.py +295 -0
- rein_agentic_kit-0.7.1/tests/test_baseline_cli.py +172 -0
- rein_agentic_kit-0.7.1/tests/test_cli_resolution.py +98 -0
- rein_agentic_kit-0.7.1/tests/test_dashboard.py +831 -0
- rein_agentic_kit-0.7.1/tests/test_dashboard_glossary.py +384 -0
- rein_agentic_kit-0.7.1/tests/test_dashboard_history.py +380 -0
- rein_agentic_kit-0.7.1/tests/test_dashboard_summary.py +260 -0
- rein_agentic_kit-0.7.1/tests/test_detect.py +151 -0
- rein_agentic_kit-0.7.1/tests/test_doctor_cli.py +309 -0
- rein_agentic_kit-0.7.1/tests/test_events.py +409 -0
- rein_agentic_kit-0.7.1/tests/test_gate.py +283 -0
- rein_agentic_kit-0.7.1/tests/test_gate_precheck.py +280 -0
- rein_agentic_kit-0.7.1/tests/test_graph_index.py +255 -0
- rein_agentic_kit-0.7.1/tests/test_graph_retrieval.py +313 -0
- rein_agentic_kit-0.7.1/tests/test_loop_policy.py +696 -0
- rein_agentic_kit-0.7.1/tests/test_measure_step.py +296 -0
- rein_agentic_kit-0.7.1/tests/test_monorepo.py +301 -0
- rein_agentic_kit-0.7.1/tests/test_packaging.py +102 -0
- rein_agentic_kit-0.7.1/tests/test_parallel_groups.py +410 -0
- rein_agentic_kit-0.7.1/tests/test_parallel_worktree_git.py +263 -0
- rein_agentic_kit-0.7.1/tests/test_plan.py +269 -0
- rein_agentic_kit-0.7.1/tests/test_plan_self_check.py +464 -0
- rein_agentic_kit-0.7.1/tests/test_python39_compat.py +72 -0
- rein_agentic_kit-0.7.1/tests/test_render_policy.py +630 -0
- rein_agentic_kit-0.7.1/tests/test_run_duration.py +369 -0
- rein_agentic_kit-0.7.1/tests/test_serena_worktree.py +140 -0
- rein_agentic_kit-0.7.1/tests/test_serve_probe.py +472 -0
- rein_agentic_kit-0.7.1/tests/test_setup.py +532 -0
- rein_agentic_kit-0.7.1/tests/test_token_report.py +229 -0
- rein_agentic_kit-0.7.1/tests/test_verify_commands.py +423 -0
- rein_agentic_kit-0.7.1/tests/test_verify_policy.py +768 -0
- rein_agentic_kit-0.7.1/tests/test_version_lock.py +51 -0
- rein_agentic_kit-0.7.1/tests/test_version_staleness.py +351 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luis Farfan
|
|
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,340 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rein-agentic-kit
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: Rein — keep your Claude Code agents lean and in control. Token-lean, stack-aware agentic dev flow.
|
|
5
|
+
Author: Luis Farfan
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/luisfarfan/rein-agentic-kit
|
|
8
|
+
Project-URL: Source, https://github.com/luisfarfan/rein-agentic-kit
|
|
9
|
+
Keywords: claude,claude-code,agents,tokens,cost,review,planning
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
<div align="center">
|
|
22
|
+
|
|
23
|
+
# 🐎 Rein
|
|
24
|
+
|
|
25
|
+
**Keep your Claude Code agents lean and in control.**
|
|
26
|
+
|
|
27
|
+
A Claude Code plugin that turns agent work into a bounded, measured, independently-reviewed flow —
|
|
28
|
+
and tells you what it actually cost, per model.
|
|
29
|
+
|
|
30
|
+
[](LICENSE)
|
|
31
|
+
[](https://github.com/luisfarfan/rein-agentic-kit/actions/workflows/ci.yml)
|
|
32
|
+
[](#)
|
|
33
|
+
[](#)
|
|
34
|
+
[](https://claude.com/claude-code)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 💸 The problem, measured
|
|
41
|
+
|
|
42
|
+
Optimizing agent cost by "making the model write less" does nothing. Over real Claude Code
|
|
43
|
+
transcripts:
|
|
44
|
+
|
|
45
|
+
| Where the tokens go | Share |
|
|
46
|
+
|---|---:|
|
|
47
|
+
| 🔴 `cache_read` — context re-read **every turn** | **~90%** |
|
|
48
|
+
| 🟠 `cache_write` | ~10% |
|
|
49
|
+
| 🟢 **output** — what a compressor would attack | **~0.3%** |
|
|
50
|
+
| ⚪ fresh input | ~0% |
|
|
51
|
+
|
|
52
|
+
**Cost ≈ turns × context size.** One agent that ran 241 turns, re-reading ~234k of context on
|
|
53
|
+
every single turn, was most of a 112M-token run.
|
|
54
|
+
|
|
55
|
+
And Claude Code has **no native eviction of stale tool results** — only `/compact`, which is
|
|
56
|
+
lossy and breaks the prompt cache. A long agent's context only grows.
|
|
57
|
+
|
|
58
|
+
> **Measured effect of this kit: 241 turns → 26 · Opus 100% → 0% · ~7× less context per turn.**
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 🔁 The flow
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
flowchart TD
|
|
66
|
+
A["🧭 /rein:plan<br/><i>Why · Scope · Decisions · Tasks</i>"]
|
|
67
|
+
B{{"rein next<br/><i>deterministic gate</i>"}}
|
|
68
|
+
C["⚙️ Implement<br/><i>bounded loop of FRESH agents</i><br/><i>context resets each step</i>"]
|
|
69
|
+
D{{"Verify<br/><i>ask the plan, not the agent</i>"}}
|
|
70
|
+
E["🔍 /rein:review<br/><i>whole change · 5 axes</i>"]
|
|
71
|
+
F["✅ merge"]
|
|
72
|
+
G["✋ escalate to you"]
|
|
73
|
+
X["🛑 stop"]
|
|
74
|
+
|
|
75
|
+
A -->|you confirm| B
|
|
76
|
+
B -->|ready| C
|
|
77
|
+
C --> D
|
|
78
|
+
D -->|contradiction| X
|
|
79
|
+
D -->|consistent| E
|
|
80
|
+
E -->|"APPROVED + gate green"| F
|
|
81
|
+
E -->|"needs your judgement"| G
|
|
82
|
+
E -->|"CHANGES_REQUESTED · max 3"| C
|
|
83
|
+
|
|
84
|
+
style A fill:#1e3a5f,stroke:#4a90d9,color:#fff
|
|
85
|
+
style C fill:#1e4620,stroke:#4caf50,color:#fff
|
|
86
|
+
style E fill:#5f1e3a,stroke:#d94a90,color:#fff
|
|
87
|
+
style F fill:#2d4a1e,stroke:#8bc34a,color:#fff
|
|
88
|
+
style X fill:#4a1e1e,stroke:#d94a4a,color:#fff
|
|
89
|
+
style G fill:#4a3a1e,stroke:#d9a94a,color:#fff
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Three roles, and **no agent approves its own implementation**. Every run works in its own git
|
|
93
|
+
worktree; unapproved work is never merged.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🚀 Quickstart
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
claude plugin marketplace add luisfarfan/rein-agentic-kit
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
claude plugin install rein@rein-agentic-kit --scope user
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Restart Claude Code**, then run inside it:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
/rein:ping → is it wired here, and what did it detect?
|
|
111
|
+
/rein:setup → probe the optional tools · confirm to provision them
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`ping` reports the detected stack, the resolved commands and where each one
|
|
115
|
+
came from. **If it got everything right, you configure nothing.**
|
|
116
|
+
|
|
117
|
+
> **Everything runs inside Claude Code — there is nothing to add to your `$PATH`.**
|
|
118
|
+
> Claude Code puts the plugin's `bin/` on the path of its own sessions, which is
|
|
119
|
+
> where the skills, the commands and the agents call `rein`. In a plain terminal
|
|
120
|
+
> `rein` will *not* be found, and that is expected: the CLI exists to be called by
|
|
121
|
+
> the flow, and the two commands a person runs by hand have slash commands above.
|
|
122
|
+
### Want `rein` in your own terminal too?
|
|
123
|
+
|
|
124
|
+
The plugin's `bin/` is only on the path of Claude Code's own sessions — a plugin
|
|
125
|
+
cannot add anything to your shell. For `rein dashboard`, `rein ledger` or
|
|
126
|
+
`rein doctor` from a terminal, install the CLI the way every tool this kit
|
|
127
|
+
integrates ships (serena and graphify via `uv`, codegraph and openspec via `npm`):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv tool install rein-agentic-kit # or: pipx install rein-agentic-kit
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Same code, same version, zero dependencies. The two channels cannot drift: a
|
|
134
|
+
test fails the build if their version strings ever disagree.
|
|
135
|
+
|
|
136
|
+
> To update: `claude plugin marketplace update rein-agentic-kit` then
|
|
137
|
+
> `claude plugin update rein@rein-agentic-kit` — qualified with the marketplace,
|
|
138
|
+
> or it reports `Plugin "rein" not found`.
|
|
139
|
+
|
|
140
|
+
Then, per change:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
/rein:plan → you confirm the plan → /rein:loop → read the verdict
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
You come back when it finished, not before.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🧰 What you get
|
|
151
|
+
|
|
152
|
+
### Skills — the three roles
|
|
153
|
+
|
|
154
|
+
| | |
|
|
155
|
+
|---|---|
|
|
156
|
+
| 🎭 **`/rein:role`** | Assign this session's role: planner · implementer · reviewer |
|
|
157
|
+
| 🧭 **`/rein:plan`** | Plan into verifiable tasks — dry-run and **explicit confirmation** before writing |
|
|
158
|
+
| 🔨 **`/rein:run`** | Exactly **one** task. Max 3 attempts, max 5 failed commands, no self-approval |
|
|
159
|
+
| 🔁 **`/rein:run-auto`** | Bounded loop of `run`, stopping on **verifiable signals** only |
|
|
160
|
+
| 🔍 **`/rein:review`** | The independent gate: mechanical checks first, then five-axis judgement |
|
|
161
|
+
| ♾️ **`/rein:loop`** | Runs all three end-to-end in an isolated worktree |
|
|
162
|
+
|
|
163
|
+
### CLI — the deterministic half
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
rein doctor # 🩺 start here: stack, resolved commands, and the source of each
|
|
167
|
+
# plus a "version : <verdict> -- <reason>" line -- up-to-date / stale /
|
|
168
|
+
# unknown against the marketplace clone, with fix commands when stale
|
|
169
|
+
# --json: {"version", "pluginRoot", "project", "plan", "verifyState",
|
|
170
|
+
# "ledger", "staleness"} -- staleness is {"verdict", "reason",
|
|
171
|
+
# "installedVersion", "availableVersion"}
|
|
172
|
+
rein setup # probe the optional tools · --install provisions what is missing
|
|
173
|
+
rein detect # stack + commands, with the source of each
|
|
174
|
+
rein tasks # the plan, parsed
|
|
175
|
+
rein context # detect + plan in ONE round-trip — what the loop's first agent runs
|
|
176
|
+
rein verify # actually RUN each resolved command and report the truth — an inference is not a fact
|
|
177
|
+
rein next # ✅ the gate: is there a task to claim, and may it be
|
|
178
|
+
rein close T001 # tick a checkbox deterministically — no agent hand-edits the plan
|
|
179
|
+
rein review # record / check a verdict bound to a code state
|
|
180
|
+
rein token-report# what a run really cost, per agent and per model
|
|
181
|
+
rein ledger # history across projects, with deltas vs a marked baseline
|
|
182
|
+
# --json: {"runs": [...], "events_by_project": {...}} -- runs are
|
|
183
|
+
# unchanged row objects; events (D3) are counted separately, never
|
|
184
|
+
# folded into a run total
|
|
185
|
+
rein baseline # mark the run everything is compared against
|
|
186
|
+
rein dashboard # 📊 serve it all as a local page
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
> **The rule that separates them:** if it's a *parse*, a script does it. If it's a *judgement*,
|
|
190
|
+
> an agent does it. Every fact an agent doesn't have to rediscover is turns you don't pay for.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## ⚖️ The three levers
|
|
195
|
+
|
|
196
|
+
**1️⃣ Bounded loop of fresh agents.** Each task is at most *N* short, fresh agents handing off a
|
|
197
|
+
**compact ledger** (`progress` / `remaining` / `filesTouched` / `verification`) — never one agent
|
|
198
|
+
running 200+ turns. Context **resets at every boundary**, so spend stops growing without a ceiling.
|
|
199
|
+
|
|
200
|
+
**2️⃣ Per-agent model routing.** Mechanical → Haiku · code → Sonnet · the review gate → Opus. On a
|
|
201
|
+
subscription this doesn't lower the bill — it frees the **scarce Opus quota**, which is the limit
|
|
202
|
+
you actually hit.
|
|
203
|
+
|
|
204
|
+
**3️⃣ Verifiable signals, not model judgement.** A loop that stops when the model *feels* finished
|
|
205
|
+
has no gate. `rein next` answers "is there work to claim" from the plan; `rein review check`
|
|
206
|
+
answers "does this approval still apply" from content hashes. Neither asks a model anything.
|
|
207
|
+
|
|
208
|
+
### ❌ Deliberately not included
|
|
209
|
+
|
|
210
|
+
Tried and discarded **with data**, not taste:
|
|
211
|
+
|
|
212
|
+
- **Output compressors** — they attack the 0.3%.
|
|
213
|
+
- **Multi-provider API swarms** — the saving doesn't apply on a subscription, and more agents means
|
|
214
|
+
more contexts re-read.
|
|
215
|
+
- **Cross-session memory tools** — orthogonal to the actual cost driver.
|
|
216
|
+
- **Cache-aware proxies** — no-op on already-cached traffic.
|
|
217
|
+
- **Persona prompts** ("you are a hexagonal architecture expert") — the same model with the same
|
|
218
|
+
weights. Constraints that can be *violated* are useful; job titles are not.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## ⚙️ Configure
|
|
223
|
+
|
|
224
|
+
Everything is optional. Drop a `flow.config.json` at your project root to override:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"commands": {
|
|
229
|
+
"test": "uv run pytest -q",
|
|
230
|
+
"testOne": "uv run pytest -q {target}",
|
|
231
|
+
"lint": "uv run ruff check .",
|
|
232
|
+
"typecheck": "uv run mypy ."
|
|
233
|
+
},
|
|
234
|
+
"models": { "aux": "haiku", "impl": "sonnet", "review": "opus" },
|
|
235
|
+
"limits": { "maxTaskSteps": 8, "maxReviewRounds": 3 }
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Precedence:** `flow.config.json` › task runner (`justfile` / `Makefile` / `Taskfile`) ›
|
|
240
|
+
autodetection. A project that already declares how it is built is never second-guessed.
|
|
241
|
+
|
|
242
|
+
## 🧱 Supported stacks
|
|
243
|
+
|
|
244
|
+
| Stack | Detected by | Verification |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| 🐍 Python | `pyproject.toml`, uv / poetry | pytest · ruff · mypy |
|
|
247
|
+
| 🟨 Node / TS | `package.json`, pnpm / npm / yarn / bun | vitest or jest · eslint · tsc |
|
|
248
|
+
| 🦀 Rust | `Cargo.toml` | cargo test · clippy · check |
|
|
249
|
+
| 🐹 Go | `go.mod` | go test · vet |
|
|
250
|
+
| 🎨 **Frontend** *(Next, Vite, Astro, SvelteKit, Nuxt, Remix)* | dependencies | **rendered verification** — unit tests alone don't catch "the tests pass but the UI is broken" |
|
|
251
|
+
| ☁️ Serverless / infra | `serverless.yml`, `sst.config.ts`, `*.tf` | `plan` / `validate` — **never deploy** |
|
|
252
|
+
| 📦 Monorepo | sub-projects one or two levels down, no root manifest | reports each sub-project and its own commands — **it never picks one for you**, even when there is only one candidate |
|
|
253
|
+
|
|
254
|
+
> **A resolved command is an inference until something runs it.** `rein verify` executes each one
|
|
255
|
+
> and reports what happened, distinguishing *"the binary is missing"* (a **setup** problem) from
|
|
256
|
+
> *"the suite ran and failed"* (a **code** problem) — conflating them sends you to the wrong file.
|
|
257
|
+
> The loop runs it at Prepare: a broken gate found there costs nothing, the same one found at
|
|
258
|
+
> review costs a whole run.
|
|
259
|
+
|
|
260
|
+
Optional tools (`serena`, `codegraph`, `graphify`, `openspec`) are **probed, never
|
|
261
|
+
required**: if one is absent the flow degrades, it does not break. `rein setup` reports
|
|
262
|
+
what is missing and installs it on request — and distinguishes *installed* from *usable*,
|
|
263
|
+
because graphify without an index and a just-registered MCP server are both present and
|
|
264
|
+
inert.
|
|
265
|
+
|
|
266
|
+
> **No retrieval speedup is claimed.** With codegraph present, the loop's implementers are
|
|
267
|
+
> taught `codegraph query` / `callers` / `callees` / `node` / `impact` (plus `sync` to
|
|
268
|
+
> refresh the index after their own edits) as the one owner of "what is this / who touches
|
|
269
|
+
> it / what breaks if I change it"; with codegraph absent, serena's `get_symbols_overview` /
|
|
270
|
+
> `find_symbol` / `find_referencing_symbols` cover the same ground as a fallback. Whether
|
|
271
|
+
> either reduces the turns an agent spends orienting is **unmeasured**, and the one control
|
|
272
|
+
> available points the other way. See [docs/decisions.md](docs/decisions.md) D2.
|
|
273
|
+
|
|
274
|
+
**One owner per question.** A tool is dropped from the prompts for having no *exclusive*
|
|
275
|
+
question — not for being bad:
|
|
276
|
+
|
|
277
|
+
```mermaid
|
|
278
|
+
flowchart LR
|
|
279
|
+
Q1["❓ what is this?<br/>who touches it?<br/>what breaks if I change it?"] --> CG["🔎 codegraph<br/><i>query · callers · callees</i><br/><i>node · impact</i>"]
|
|
280
|
+
Q2["❓ edit this symbol<br/>type errors, no build"] --> SE["✏️ serena<br/><i>replace_symbol_body</i><br/><i>get_diagnostics_for_file</i>"]
|
|
281
|
+
Q3["❓ docs · papers · images"] --> GR["📚 graphify<br/><i>/graphify skill</i><br/><i>outside the loop</i>"]
|
|
282
|
+
|
|
283
|
+
style CG fill:#1e4620,stroke:#4caf50,color:#fff
|
|
284
|
+
style SE fill:#1e3a5f,stroke:#4a90d9,color:#fff
|
|
285
|
+
style GR fill:#4a3a1e,stroke:#d9a94a,color:#fff
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Measured on this repo, same question, same index cost (~1.5s, no LLM, no API key for either):
|
|
289
|
+
asked *"where is it decided that a command is not invocable?"*, codegraph returns
|
|
290
|
+
`NOT_INVOCABLE_EXIT_CODES = (126,127)` with its file and line in **258 tokens**; the graph
|
|
291
|
+
tool it replaced returned **546 tokens of an unrelated example config**, because a JSON key
|
|
292
|
+
happened to match. Confident noise is worse for an agent than no answer — it cannot tell the
|
|
293
|
+
two apart, and it pays for the difference on every later turn.
|
|
294
|
+
|
|
295
|
+
## 📊 Measure
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
rein token-report && rein dashboard
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Reads Claude Code's own JSONL transcripts (including `cache_read`) and breaks a run down per
|
|
302
|
+
agent and **per model**. Every run is summarized into `~/.claude/rein/runs.jsonl`, so history
|
|
303
|
+
survives transcript rotation.
|
|
304
|
+
|
|
305
|
+
**On the word "savings":** this measures *consumption*. A saving needs a baseline. Mark one with
|
|
306
|
+
`rein baseline mark` and every later run in that project gets a signed delta. Without one, the
|
|
307
|
+
honest numbers are the three that predict cost — **turns/agent**, **ctx_max/turn**,
|
|
308
|
+
**% of tokens on Opus**.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 🙃 Honest limitations
|
|
313
|
+
|
|
314
|
+
Things a README usually hides:
|
|
315
|
+
|
|
316
|
+
- **The reviewer is calibrated hard.** 4 of 6 runs here exhausted their 3 rounds. A three-task
|
|
317
|
+
change will often use them all.
|
|
318
|
+
- **A stalled agent burns wall-clock.** One run spent 3.4 hours almost entirely in silent API
|
|
319
|
+
retries.
|
|
320
|
+
- **`discover` was considered and rejected** — a per-run version of it was measured in the origin
|
|
321
|
+
project and did not move the needle. See [docs/decisions.md](docs/decisions.md).
|
|
322
|
+
|
|
323
|
+
## 🗺️ Roadmap
|
|
324
|
+
|
|
325
|
+
| Phase | Scope | |
|
|
326
|
+
|---|---|---|
|
|
327
|
+
| 0 | Plugin plumbing · `token-report` · ledger · stack detection | ✅ [findings](docs/phase-0-findings.md) |
|
|
328
|
+
| 1 | Config-driven core loop · `tasks.md` adapter — **measured** | ✅ |
|
|
329
|
+
| 2 | Stack-aware verification policy | ✅ |
|
|
330
|
+
| 3 | Local dashboard · per-agent model config | ✅ |
|
|
331
|
+
| 4 | Compose real browser verification | ✅ |
|
|
332
|
+
| 5 | Docs · polish · a second real-world project | ⏳ |
|
|
333
|
+
|
|
334
|
+
## 📄 License
|
|
335
|
+
|
|
336
|
+
MIT — see [LICENSE](LICENSE).
|
|
337
|
+
|
|
338
|
+
<div align="center">
|
|
339
|
+
<sub>Built with Claude Code, reviewed by an agent that wrote none of it.</sub>
|
|
340
|
+
</div>
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🐎 Rein
|
|
4
|
+
|
|
5
|
+
**Keep your Claude Code agents lean and in control.**
|
|
6
|
+
|
|
7
|
+
A Claude Code plugin that turns agent work into a bounded, measured, independently-reviewed flow —
|
|
8
|
+
and tells you what it actually cost, per model.
|
|
9
|
+
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://github.com/luisfarfan/rein-agentic-kit/actions/workflows/ci.yml)
|
|
12
|
+
[](#)
|
|
13
|
+
[](#)
|
|
14
|
+
[](https://claude.com/claude-code)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 💸 The problem, measured
|
|
21
|
+
|
|
22
|
+
Optimizing agent cost by "making the model write less" does nothing. Over real Claude Code
|
|
23
|
+
transcripts:
|
|
24
|
+
|
|
25
|
+
| Where the tokens go | Share |
|
|
26
|
+
|---|---:|
|
|
27
|
+
| 🔴 `cache_read` — context re-read **every turn** | **~90%** |
|
|
28
|
+
| 🟠 `cache_write` | ~10% |
|
|
29
|
+
| 🟢 **output** — what a compressor would attack | **~0.3%** |
|
|
30
|
+
| ⚪ fresh input | ~0% |
|
|
31
|
+
|
|
32
|
+
**Cost ≈ turns × context size.** One agent that ran 241 turns, re-reading ~234k of context on
|
|
33
|
+
every single turn, was most of a 112M-token run.
|
|
34
|
+
|
|
35
|
+
And Claude Code has **no native eviction of stale tool results** — only `/compact`, which is
|
|
36
|
+
lossy and breaks the prompt cache. A long agent's context only grows.
|
|
37
|
+
|
|
38
|
+
> **Measured effect of this kit: 241 turns → 26 · Opus 100% → 0% · ~7× less context per turn.**
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🔁 The flow
|
|
43
|
+
|
|
44
|
+
```mermaid
|
|
45
|
+
flowchart TD
|
|
46
|
+
A["🧭 /rein:plan<br/><i>Why · Scope · Decisions · Tasks</i>"]
|
|
47
|
+
B{{"rein next<br/><i>deterministic gate</i>"}}
|
|
48
|
+
C["⚙️ Implement<br/><i>bounded loop of FRESH agents</i><br/><i>context resets each step</i>"]
|
|
49
|
+
D{{"Verify<br/><i>ask the plan, not the agent</i>"}}
|
|
50
|
+
E["🔍 /rein:review<br/><i>whole change · 5 axes</i>"]
|
|
51
|
+
F["✅ merge"]
|
|
52
|
+
G["✋ escalate to you"]
|
|
53
|
+
X["🛑 stop"]
|
|
54
|
+
|
|
55
|
+
A -->|you confirm| B
|
|
56
|
+
B -->|ready| C
|
|
57
|
+
C --> D
|
|
58
|
+
D -->|contradiction| X
|
|
59
|
+
D -->|consistent| E
|
|
60
|
+
E -->|"APPROVED + gate green"| F
|
|
61
|
+
E -->|"needs your judgement"| G
|
|
62
|
+
E -->|"CHANGES_REQUESTED · max 3"| C
|
|
63
|
+
|
|
64
|
+
style A fill:#1e3a5f,stroke:#4a90d9,color:#fff
|
|
65
|
+
style C fill:#1e4620,stroke:#4caf50,color:#fff
|
|
66
|
+
style E fill:#5f1e3a,stroke:#d94a90,color:#fff
|
|
67
|
+
style F fill:#2d4a1e,stroke:#8bc34a,color:#fff
|
|
68
|
+
style X fill:#4a1e1e,stroke:#d94a4a,color:#fff
|
|
69
|
+
style G fill:#4a3a1e,stroke:#d9a94a,color:#fff
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Three roles, and **no agent approves its own implementation**. Every run works in its own git
|
|
73
|
+
worktree; unapproved work is never merged.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🚀 Quickstart
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
claude plugin marketplace add luisfarfan/rein-agentic-kit
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
claude plugin install rein@rein-agentic-kit --scope user
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Restart Claude Code**, then run inside it:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
/rein:ping → is it wired here, and what did it detect?
|
|
91
|
+
/rein:setup → probe the optional tools · confirm to provision them
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`ping` reports the detected stack, the resolved commands and where each one
|
|
95
|
+
came from. **If it got everything right, you configure nothing.**
|
|
96
|
+
|
|
97
|
+
> **Everything runs inside Claude Code — there is nothing to add to your `$PATH`.**
|
|
98
|
+
> Claude Code puts the plugin's `bin/` on the path of its own sessions, which is
|
|
99
|
+
> where the skills, the commands and the agents call `rein`. In a plain terminal
|
|
100
|
+
> `rein` will *not* be found, and that is expected: the CLI exists to be called by
|
|
101
|
+
> the flow, and the two commands a person runs by hand have slash commands above.
|
|
102
|
+
### Want `rein` in your own terminal too?
|
|
103
|
+
|
|
104
|
+
The plugin's `bin/` is only on the path of Claude Code's own sessions — a plugin
|
|
105
|
+
cannot add anything to your shell. For `rein dashboard`, `rein ledger` or
|
|
106
|
+
`rein doctor` from a terminal, install the CLI the way every tool this kit
|
|
107
|
+
integrates ships (serena and graphify via `uv`, codegraph and openspec via `npm`):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
uv tool install rein-agentic-kit # or: pipx install rein-agentic-kit
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Same code, same version, zero dependencies. The two channels cannot drift: a
|
|
114
|
+
test fails the build if their version strings ever disagree.
|
|
115
|
+
|
|
116
|
+
> To update: `claude plugin marketplace update rein-agentic-kit` then
|
|
117
|
+
> `claude plugin update rein@rein-agentic-kit` — qualified with the marketplace,
|
|
118
|
+
> or it reports `Plugin "rein" not found`.
|
|
119
|
+
|
|
120
|
+
Then, per change:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
/rein:plan → you confirm the plan → /rein:loop → read the verdict
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
You come back when it finished, not before.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🧰 What you get
|
|
131
|
+
|
|
132
|
+
### Skills — the three roles
|
|
133
|
+
|
|
134
|
+
| | |
|
|
135
|
+
|---|---|
|
|
136
|
+
| 🎭 **`/rein:role`** | Assign this session's role: planner · implementer · reviewer |
|
|
137
|
+
| 🧭 **`/rein:plan`** | Plan into verifiable tasks — dry-run and **explicit confirmation** before writing |
|
|
138
|
+
| 🔨 **`/rein:run`** | Exactly **one** task. Max 3 attempts, max 5 failed commands, no self-approval |
|
|
139
|
+
| 🔁 **`/rein:run-auto`** | Bounded loop of `run`, stopping on **verifiable signals** only |
|
|
140
|
+
| 🔍 **`/rein:review`** | The independent gate: mechanical checks first, then five-axis judgement |
|
|
141
|
+
| ♾️ **`/rein:loop`** | Runs all three end-to-end in an isolated worktree |
|
|
142
|
+
|
|
143
|
+
### CLI — the deterministic half
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
rein doctor # 🩺 start here: stack, resolved commands, and the source of each
|
|
147
|
+
# plus a "version : <verdict> -- <reason>" line -- up-to-date / stale /
|
|
148
|
+
# unknown against the marketplace clone, with fix commands when stale
|
|
149
|
+
# --json: {"version", "pluginRoot", "project", "plan", "verifyState",
|
|
150
|
+
# "ledger", "staleness"} -- staleness is {"verdict", "reason",
|
|
151
|
+
# "installedVersion", "availableVersion"}
|
|
152
|
+
rein setup # probe the optional tools · --install provisions what is missing
|
|
153
|
+
rein detect # stack + commands, with the source of each
|
|
154
|
+
rein tasks # the plan, parsed
|
|
155
|
+
rein context # detect + plan in ONE round-trip — what the loop's first agent runs
|
|
156
|
+
rein verify # actually RUN each resolved command and report the truth — an inference is not a fact
|
|
157
|
+
rein next # ✅ the gate: is there a task to claim, and may it be
|
|
158
|
+
rein close T001 # tick a checkbox deterministically — no agent hand-edits the plan
|
|
159
|
+
rein review # record / check a verdict bound to a code state
|
|
160
|
+
rein token-report# what a run really cost, per agent and per model
|
|
161
|
+
rein ledger # history across projects, with deltas vs a marked baseline
|
|
162
|
+
# --json: {"runs": [...], "events_by_project": {...}} -- runs are
|
|
163
|
+
# unchanged row objects; events (D3) are counted separately, never
|
|
164
|
+
# folded into a run total
|
|
165
|
+
rein baseline # mark the run everything is compared against
|
|
166
|
+
rein dashboard # 📊 serve it all as a local page
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
> **The rule that separates them:** if it's a *parse*, a script does it. If it's a *judgement*,
|
|
170
|
+
> an agent does it. Every fact an agent doesn't have to rediscover is turns you don't pay for.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## ⚖️ The three levers
|
|
175
|
+
|
|
176
|
+
**1️⃣ Bounded loop of fresh agents.** Each task is at most *N* short, fresh agents handing off a
|
|
177
|
+
**compact ledger** (`progress` / `remaining` / `filesTouched` / `verification`) — never one agent
|
|
178
|
+
running 200+ turns. Context **resets at every boundary**, so spend stops growing without a ceiling.
|
|
179
|
+
|
|
180
|
+
**2️⃣ Per-agent model routing.** Mechanical → Haiku · code → Sonnet · the review gate → Opus. On a
|
|
181
|
+
subscription this doesn't lower the bill — it frees the **scarce Opus quota**, which is the limit
|
|
182
|
+
you actually hit.
|
|
183
|
+
|
|
184
|
+
**3️⃣ Verifiable signals, not model judgement.** A loop that stops when the model *feels* finished
|
|
185
|
+
has no gate. `rein next` answers "is there work to claim" from the plan; `rein review check`
|
|
186
|
+
answers "does this approval still apply" from content hashes. Neither asks a model anything.
|
|
187
|
+
|
|
188
|
+
### ❌ Deliberately not included
|
|
189
|
+
|
|
190
|
+
Tried and discarded **with data**, not taste:
|
|
191
|
+
|
|
192
|
+
- **Output compressors** — they attack the 0.3%.
|
|
193
|
+
- **Multi-provider API swarms** — the saving doesn't apply on a subscription, and more agents means
|
|
194
|
+
more contexts re-read.
|
|
195
|
+
- **Cross-session memory tools** — orthogonal to the actual cost driver.
|
|
196
|
+
- **Cache-aware proxies** — no-op on already-cached traffic.
|
|
197
|
+
- **Persona prompts** ("you are a hexagonal architecture expert") — the same model with the same
|
|
198
|
+
weights. Constraints that can be *violated* are useful; job titles are not.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## ⚙️ Configure
|
|
203
|
+
|
|
204
|
+
Everything is optional. Drop a `flow.config.json` at your project root to override:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"commands": {
|
|
209
|
+
"test": "uv run pytest -q",
|
|
210
|
+
"testOne": "uv run pytest -q {target}",
|
|
211
|
+
"lint": "uv run ruff check .",
|
|
212
|
+
"typecheck": "uv run mypy ."
|
|
213
|
+
},
|
|
214
|
+
"models": { "aux": "haiku", "impl": "sonnet", "review": "opus" },
|
|
215
|
+
"limits": { "maxTaskSteps": 8, "maxReviewRounds": 3 }
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Precedence:** `flow.config.json` › task runner (`justfile` / `Makefile` / `Taskfile`) ›
|
|
220
|
+
autodetection. A project that already declares how it is built is never second-guessed.
|
|
221
|
+
|
|
222
|
+
## 🧱 Supported stacks
|
|
223
|
+
|
|
224
|
+
| Stack | Detected by | Verification |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| 🐍 Python | `pyproject.toml`, uv / poetry | pytest · ruff · mypy |
|
|
227
|
+
| 🟨 Node / TS | `package.json`, pnpm / npm / yarn / bun | vitest or jest · eslint · tsc |
|
|
228
|
+
| 🦀 Rust | `Cargo.toml` | cargo test · clippy · check |
|
|
229
|
+
| 🐹 Go | `go.mod` | go test · vet |
|
|
230
|
+
| 🎨 **Frontend** *(Next, Vite, Astro, SvelteKit, Nuxt, Remix)* | dependencies | **rendered verification** — unit tests alone don't catch "the tests pass but the UI is broken" |
|
|
231
|
+
| ☁️ Serverless / infra | `serverless.yml`, `sst.config.ts`, `*.tf` | `plan` / `validate` — **never deploy** |
|
|
232
|
+
| 📦 Monorepo | sub-projects one or two levels down, no root manifest | reports each sub-project and its own commands — **it never picks one for you**, even when there is only one candidate |
|
|
233
|
+
|
|
234
|
+
> **A resolved command is an inference until something runs it.** `rein verify` executes each one
|
|
235
|
+
> and reports what happened, distinguishing *"the binary is missing"* (a **setup** problem) from
|
|
236
|
+
> *"the suite ran and failed"* (a **code** problem) — conflating them sends you to the wrong file.
|
|
237
|
+
> The loop runs it at Prepare: a broken gate found there costs nothing, the same one found at
|
|
238
|
+
> review costs a whole run.
|
|
239
|
+
|
|
240
|
+
Optional tools (`serena`, `codegraph`, `graphify`, `openspec`) are **probed, never
|
|
241
|
+
required**: if one is absent the flow degrades, it does not break. `rein setup` reports
|
|
242
|
+
what is missing and installs it on request — and distinguishes *installed* from *usable*,
|
|
243
|
+
because graphify without an index and a just-registered MCP server are both present and
|
|
244
|
+
inert.
|
|
245
|
+
|
|
246
|
+
> **No retrieval speedup is claimed.** With codegraph present, the loop's implementers are
|
|
247
|
+
> taught `codegraph query` / `callers` / `callees` / `node` / `impact` (plus `sync` to
|
|
248
|
+
> refresh the index after their own edits) as the one owner of "what is this / who touches
|
|
249
|
+
> it / what breaks if I change it"; with codegraph absent, serena's `get_symbols_overview` /
|
|
250
|
+
> `find_symbol` / `find_referencing_symbols` cover the same ground as a fallback. Whether
|
|
251
|
+
> either reduces the turns an agent spends orienting is **unmeasured**, and the one control
|
|
252
|
+
> available points the other way. See [docs/decisions.md](docs/decisions.md) D2.
|
|
253
|
+
|
|
254
|
+
**One owner per question.** A tool is dropped from the prompts for having no *exclusive*
|
|
255
|
+
question — not for being bad:
|
|
256
|
+
|
|
257
|
+
```mermaid
|
|
258
|
+
flowchart LR
|
|
259
|
+
Q1["❓ what is this?<br/>who touches it?<br/>what breaks if I change it?"] --> CG["🔎 codegraph<br/><i>query · callers · callees</i><br/><i>node · impact</i>"]
|
|
260
|
+
Q2["❓ edit this symbol<br/>type errors, no build"] --> SE["✏️ serena<br/><i>replace_symbol_body</i><br/><i>get_diagnostics_for_file</i>"]
|
|
261
|
+
Q3["❓ docs · papers · images"] --> GR["📚 graphify<br/><i>/graphify skill</i><br/><i>outside the loop</i>"]
|
|
262
|
+
|
|
263
|
+
style CG fill:#1e4620,stroke:#4caf50,color:#fff
|
|
264
|
+
style SE fill:#1e3a5f,stroke:#4a90d9,color:#fff
|
|
265
|
+
style GR fill:#4a3a1e,stroke:#d9a94a,color:#fff
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Measured on this repo, same question, same index cost (~1.5s, no LLM, no API key for either):
|
|
269
|
+
asked *"where is it decided that a command is not invocable?"*, codegraph returns
|
|
270
|
+
`NOT_INVOCABLE_EXIT_CODES = (126,127)` with its file and line in **258 tokens**; the graph
|
|
271
|
+
tool it replaced returned **546 tokens of an unrelated example config**, because a JSON key
|
|
272
|
+
happened to match. Confident noise is worse for an agent than no answer — it cannot tell the
|
|
273
|
+
two apart, and it pays for the difference on every later turn.
|
|
274
|
+
|
|
275
|
+
## 📊 Measure
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
rein token-report && rein dashboard
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Reads Claude Code's own JSONL transcripts (including `cache_read`) and breaks a run down per
|
|
282
|
+
agent and **per model**. Every run is summarized into `~/.claude/rein/runs.jsonl`, so history
|
|
283
|
+
survives transcript rotation.
|
|
284
|
+
|
|
285
|
+
**On the word "savings":** this measures *consumption*. A saving needs a baseline. Mark one with
|
|
286
|
+
`rein baseline mark` and every later run in that project gets a signed delta. Without one, the
|
|
287
|
+
honest numbers are the three that predict cost — **turns/agent**, **ctx_max/turn**,
|
|
288
|
+
**% of tokens on Opus**.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 🙃 Honest limitations
|
|
293
|
+
|
|
294
|
+
Things a README usually hides:
|
|
295
|
+
|
|
296
|
+
- **The reviewer is calibrated hard.** 4 of 6 runs here exhausted their 3 rounds. A three-task
|
|
297
|
+
change will often use them all.
|
|
298
|
+
- **A stalled agent burns wall-clock.** One run spent 3.4 hours almost entirely in silent API
|
|
299
|
+
retries.
|
|
300
|
+
- **`discover` was considered and rejected** — a per-run version of it was measured in the origin
|
|
301
|
+
project and did not move the needle. See [docs/decisions.md](docs/decisions.md).
|
|
302
|
+
|
|
303
|
+
## 🗺️ Roadmap
|
|
304
|
+
|
|
305
|
+
| Phase | Scope | |
|
|
306
|
+
|---|---|---|
|
|
307
|
+
| 0 | Plugin plumbing · `token-report` · ledger · stack detection | ✅ [findings](docs/phase-0-findings.md) |
|
|
308
|
+
| 1 | Config-driven core loop · `tasks.md` adapter — **measured** | ✅ |
|
|
309
|
+
| 2 | Stack-aware verification policy | ✅ |
|
|
310
|
+
| 3 | Local dashboard · per-agent model config | ✅ |
|
|
311
|
+
| 4 | Compose real browser verification | ✅ |
|
|
312
|
+
| 5 | Docs · polish · a second real-world project | ⏳ |
|
|
313
|
+
|
|
314
|
+
## 📄 License
|
|
315
|
+
|
|
316
|
+
MIT — see [LICENSE](LICENSE).
|
|
317
|
+
|
|
318
|
+
<div align="center">
|
|
319
|
+
<sub>Built with Claude Code, reviewed by an agent that wrote none of it.</sub>
|
|
320
|
+
</div>
|