v0.2.0 is out: APIs and CLIs too · free & MIT

Your agent says “done.”
Your app is on fire.

thisisfine turns every behaviour you said yes to into a locked, proven check, in a browser, over HTTP or through your CLI, and won't let your coding agent finish a turn that breaks one. For Claude Code, Codex and pi.

Browser · API · CLIZero runtime depsSigned, in git
The thisisfine mascot: a calm coffee mug with a padlock on its chest, raising a tiny cup while flames burn below
☕ This is fine. 3/3 kept.

30 seconds

Watch your agent get caught

It worked yesterday. You checked it yourself and told your agent “perfect”. Today it tidied up some code, and the thing you checked is quietly broken. Nobody noticed, because the only record that it ever worked was one word in a chat that's long gone.

thisisfine keeps that word.

The 30-second story

A real run, not a mock-up

These are the exact messages from the example shop, the same steps the end-to-end test replays in a real browser.

1

You ask for a cart badge. The agent writes a check, and thisisfine proves it can fail.

Lock in promise #1 "Adding a coffee twice shows 2 on the cart badge"? ✔ passes now ✔ fails on HEAD (app still boots) Reply y to confirm, anything else to skip.
2

You reply y, perfect. It's locked, in your own words.

🔒 Locked promise #1 "Adding a coffee twice shows 2 on the cart badge".
3

Weeks later, “a small cleanup” counts products instead of items. The agent tries to stop, and can't.

🔥 This is NOT fine. You broke promise #1 "Adding a coffee twice shows 2 on the cart badge". The human confirmed it on Oct 4: "y, perfect" Failure: Expected: "2" Received: "1" Fix the app so #1 holds again. Do not edit the checks, the ledger, or the config.
The shop when you said yes: two House blends added, the cart badge shows 2
When you said yes: the badge shows 2
The same shop after the refactor: two House blends added, the cart badge shows 1
After the “cleanup”: it shows 1
4

It fixes the app, not the check. You get your coffee back.

☕ This is fine. 1/1 promises kept.

How it works

One sentence. One check. Your “y”.

Agent-written tests encode whatever the code does, bugs included. A promise encodes what a person looked at and agreed to.

you: “perfect”→agent writes a check→thisisfine proves it→you: “y”→🔒 locked
🧪

Proven, not trusted

The check must pass on your code now, and fail on a version without the change while the app still boots. A check that can't fail is labelled 🟡 unproven.

🙋

Only you can lock it

Your reply goes through a hook, not through the agent. A whole-message yes (y, lock it, 👍, haan) locks it. “Yes but make it blue” doesn't.

🚧

Every stop is a gate

Before the agent can end a turn, every promise runs: in a real browser, against your API, or through your CLI. Broken? It's sent back with your words, the assertion and a screenshot or the HTTP exchange.

✍️

Signed and in git

Every lock is signed with Ed25519 and kept in an append-only ledger. thisisfine verify audits each one, on any machine.

⚡

Free when nothing changed

The gate hashes your working tree and skips the run if it matches the last green one. On the example shop, a passing gate takes about 1.3 s.

🗳️

Change your mind, out loud

/retire 3 we're dropping the badge asks you to confirm. Only your y retires a promise, never the agent's.

Install

Thirty seconds. Zero config.

You need Node 22.18 or newer, git, and a web app that starts with one command.

# in Claude Code /plugin marketplace add dadwritestech/thisisfine /plugin install thisisfine@thisisfine
# then, in your project /promise the cart badge shows how many items are in the cart

In CI

A behaviour diff on every PR

The GitHub Action runs every promise the same way, fails the job if one is broken, and comments what the PR does to the promises, not just to the code.

# .github/workflows/promises.yml name: promises on: pull_request permissions: contents: read pull-requests: write jobs: thisisfine: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npm ci - uses: dadwritestech/thisisfine@v0
thisisfine: what this branch does to the promises (vs 4f1c2e9)✗ #1 broken: "Adding a coffee twice shows 2 on the cart badge" Expected: "2" Received: "1" + #4 locked: "Logged-out visitors are sent to /login" ✅ proven - #2 retired: "The footer shows the opening hours" ? #5 waiting for a human y: "Search finds a coffee by name" ✔ 2 promises kept (#3, #4)

Listed on the GitHub Marketplace.

What it can't do

It makes cheating loud

thisisfine can't stop an agent that is determined to cheat. Here's exactly where the edges are.

FAQ

Fair questions

Why not just ask the agent to write tests?

Because it writes tests for the code it wrote, and can edit them when they get in the way. A promise starts from you saying yes, is proven to fail without the behaviour, and is locked against edits.

Will it slow my agent down?

A turn that changed nothing costs nothing. A turn that changed code costs one app boot plus your checks, about a second for the example shop. A failing check takes longer, but that's the turn you wanted stopped.

What if a check is flaky or the app won't start?

Flaky checks warn and don't block. If the app can't start, the agent is blocked with the start error, because “couldn't check” isn't “fine”. Three identical blocks in a row and thisisfine hands the decision to you, so you're never stuck in a loop.

Do I need to know how to write tests?

No. You say “perfect” when something works and the agent asks if you want to lock it in. From then on, if it breaks it, it finds out before you do, and has to fix it before it can say it's done.

Why the name?

It's the face every coding agent makes while it reports success from inside a burning building. The phrase comes from KC Green's comic On Fire. thisisfine isn't affiliated with it, and the art here is original.

Keep the coffee hot.
Star thisisfine.

It's free, MIT, and built by one person. A star is how other developers find it, and how I know to keep going.

Star on GitHub