Dev.to WebDev 🛠 Dev 👁 0 📖 3 min read

My agent said done. Kane had to watch it fail first.

The most expensive word a coding agent says is "done". The ticket says done, the test is green, and later I find out the test would have been green anyway, or the fix broke something else. So for the Kane CLI hackathon

The most expensive word a coding agent says is "done". The ticket says done, the test is green, and later I find out the test would have been green anyway, or the fix broke something else.

So for the Kane CLI hackathon I built Proven: a ticket board where a ticket closes only after Kane CLI watched its frozen test fail before the change and pass after it.

Red first

A person writes the ticket and a plain-English Kane test. Proven freezes the test before any work starts: it commits the ticket and the test, then a lock that names that commit. Then Kane has to fail the test on the app as it is. If the test already passes, it proves nothing, and Proven says so.

The first thing I did was test how Kane fails. With my server down, an "open the page" step passed on Chrome's error page and the next step failed, so an outage looked exactly like a real bug. Now step 1 of every frozen test checks a landmark, and Proven checks that the app answers before it starts Kane. An outage is "did not run", never red.

One command closes the loop

After red, proven loop hands the ticket to the coding agent, Claude Code running headless. The agent's only way to say done is proven done. Proven serves a snapshot of the change and runs Kane on the frozen test:

  • a fail goes back to the agent with the failing step and Kane's own words
  • a pass commits exactly what Kane judged, then a receipt that links red, green and the test's hash

Then the loop does not trust that pass. It reruns every closed ticket with fresh Kane runs.

What happened in the recorded run

The demo shop has three tickets. Ticket 3 asks the cart to take coupon codes from marketing's coupons.json. Kane failed it first: "The cart rejects the required FALL15 coupon, so the order total remains $30.00 instead of $26.25."

I wrote ticket 3 so that its plain reading breaks ticket 1, and that is what the agent did, in all four live runs that day, the last one from a fresh clone that followed only the README. It fixed ticket 3 on the first try, but the new code only read coupons.json, and SAVE10 from ticket 1 was not in it. The recheck caught it. A fresh Kane run failed ticket 1, and a second run failed it again: "The cart rejects the valid SAVE10 coupon, so the order total remains $30.00 instead of $27.50."

Ticket 1 reopened, and the loop handed it back. The agent said: "The SAVE10 code is missing from coupons.json. With a $25.00 subtotal, 10% off ($2.50) plus $5.00 shipping gives the expected $27.50." It added the code, Kane passed it, and a final recheck passed all three. Nobody typed anything between the first command and the last line.

Anyone can re-check

proven verify receipts/T-1.json checks a receipt with git alone. --replay serves the app as it was at the red commit and at the green commit and runs Kane on both: it has to fail at red and pass at green.

What's rough

  • Receipts are tamper-evident, not tamper-proof. An agent with a shell could forge local history, so the board shows done only for a receipt that verifies, and the strongest check is someone else running verify --replay.
  • It serves static web apps only for now. I also ran it once on the TodoMVC example, an app I didn't write: Kane failed a new "Clear completed (2)" test, the agent fixed it, and Kane passed it (docs/own-app.md in the repo).
  • Kane's recordings and evidence packs stay on my machine because they carry account ids. Receipts keep their hashes.

Try it

git clone https://github.com/vijaygopalbalasa/proven
cd proven
npm start

That opens the board over the real receipts, with nothing to install. To run the loop yourself, git checkout try-it and follow the README.

Built with Claude Code, tested with Kane CLI from TestMu AI. #KaneCLIHackathon

I wrote this post with help from AI.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.