Try it yourself — make a bug stay fixed¶
A complete, copy-paste walkthrough on a repo you build from scratch in 3 minutes. By the end you'll have seen Verel do the three things it exists to do, on your own machine:
- Catch a real bug — turn a failing test into a grounded
FAILverdict (not an opinion). - Confirm the fix — the same gate flips to
PASSonly when the grader actually passes. - Remember it — the fixed bug is recorded so a silent reintroduction is blocked from memory alone, no re-run needed.
Steps 1–3 need no API key — they're deterministic, so the output below is exactly what you'll see. (The optional finale lets an LLM do the fixing.)
Every output block here is real captured output from running these exact commands — nothing is mocked.
0. Install (30s)¶
pip install "verel[dev]" # core + the pytest / ruff / mypy graders
verel doctor # sanity-check your environment
verel doctor ends with the memory backend it will use:
verel 1.9.4
...
-> memory backend: local (available: lancedb, local, postgres, redis, remote)
1. A repo with a real bug (1 min)¶
A tiny tax helper with a genuine defect — it forgets to add the tax — and a test that catches it:
mkdir taxes-demo && cd taxes-demo
# taxes.py
def subtotal(prices):
return sum(prices)
def total_with_tax(prices, rate):
# BUG: forgets to add the tax — returns the pre-tax subtotal
return subtotal(prices)
# test_taxes.py
from taxes import total_with_tax
def test_applies_tax():
# $100 of goods at 10% tax must be $110
assert total_with_tax([60, 40], 0.10) == 110.0
Now gate the repo — unify tests + lint + types into one verdict:
verel-ci check --repo .
[inner_loop:python] verdict=fail
- test: 1 issue(s)
test:error test_taxes.py::test_applies_tax assert 100 == 110.0
The process exits non-zero (echo $? → 1), so this is a hard CI gate, and the failure is
grounded — it points at the exact test and the exact assertion that failed. No agent gets to
call this "done."
2. Fix it — the gate flips to PASS (30s)¶
Apply the tax:
# taxes.py
def subtotal(prices):
return sum(prices)
def total_with_tax(prices, rate):
return round(subtotal(prices) * (1 + rate), 2)
verel-ci check --repo .
[inner_loop:python] verdict=pass
Exit 0. The verdict flipped to pass because the real grader passed — not because anyone
claimed it did.
3. Make the fix stick — remember the bug (1 min)¶
This is what makes Verel a brain and not just a linter: a fixed failure is remembered, so if the same bug sneaks back in a future change it's caught from memory alone, with no test re-run.
# remember_the_bug.py
import pathlib
from verel.ci import inner_loop_stage, run_stage
from verel.memory import FailureLedger, LocalMemory
mem = LocalMemory("brain.db") # a real on-disk brain (swap for an external DB — see below)
ledger = FailureLedger(mem, scope="repo:taxes") # scope = "where does this live?"; recall picks the most specific match (self → team → org → global)
# Re-break the code to capture a REAL failing verdict from the grader:
good = pathlib.Path("taxes.py").read_text()
pathlib.Path("taxes.py").write_text(good.replace("* (1 + rate), 2)", "), 2) # tax dropped again"))
fail = run_stage(inner_loop_stage(".", with_lint=False, with_types=False))
print("gate verdict:", fail.verdict.value)
fps = []
for r in fail.reports:
fps += ledger.record(r) # remember every grounded failure
print("recorded fingerprints:", len(fps))
ledger.mark_fixed(fps) # ...we fix it
pathlib.Path("taxes.py").write_text(good)
print("marked fixed:", len(fps))
# ...later the same bug sneaks back in a new change. Caught from MEMORY alone — no re-run:
regs = [g for r in fail.reports for g in ledger.check_regressions(r)]
print("regression blocked from memory:", bool(regs))
python remember_the_bug.py
gate verdict: fail
recorded fingerprints: 1
marked fixed: 1
regression blocked from memory: True
regression blocked from memory: True is the payoff — Verel recognized the returning bug from its
fingerprint without re-running the suite. A fix, once verified, compounds.
Point the brain at an external store (out of the box)¶
That brain.db is the zero-dependency default. The brain is pluggable — select a backend by
name with one env var, no code change:
export VEREL_MEMORY_BACKEND=local # the default (SQLite)
export VEREL_MEMORY_STORE=team-brain.db # or any path
verel doctor # confirms: -> memory backend: local (available: lancedb, local, postgres, redis, remote)
from verel.memory import load_backend, known_backends
print(known_backends()) # ['lancedb', 'local', 'postgres', 'redis', 'remote']
brain = load_backend("local") # resolved by name through the backend registry
remote points a whole fleet at one shared, authenticated brain (VEREL_BRAIN_URL). External
databases (Postgres/pgvector, LanceDB, Redis) ship as pip install verel[<db>] extras that register
under the same selector — see Configuration. The trust layer
(corroborate / supersede / recall / the regression guard you just used) is identical whichever
backend is selected.
Optional: let an agent fix it for you¶
Steps 1–3 had you write the fix. With an LLM key, an agent does it — it reads only the grader's findings (never the test), patches the source, and loops until the graders themselves go green:
# default LLM is Ollama Cloud (~/.config/ollama/key); set VEREL_LLM_PROVIDER=openai to switch
verel heal --repo .
For a self-contained version that builds its own broken repo, run
examples/demo_selfheal.py:
round 1: verdict=fail medic=['fix_branch'] patched=['mathx.py', 'strx.py']
round 2: verdict=pass medic=[] patched=[]
healed=True terminated_on=passed
terminated_on=passed means the loop stopped because the graders went green — not because the
agent said so.
What you just proved¶
| Step | Capability | What decided "done" |
|---|---|---|
| 1 | The gate catches a real bug, grounded at file::test |
the pytest grader, not a claim |
| 2 | The gate flips to PASS only on a real pass | the grader's verdict |
| 3 | A fixed bug is remembered; a reintroduction is blocked from memory | the failure ledger |
| ↪ | The brain is pluggable (local → remote → external DB) | one env var, same contract |
Next: the 5-minute tutorial (hollow-pass rejection, polyglot CI, attested receipts), the real-world scenarios with captured output, or the use cases by persona.