noworries: verifying what the AI just changed
The bottleneck isn’t writing code anymore
An AI agent — Claude Code, Cursor, Copilot, pick one — writes the feature. The diff looks fine. Types check, unit tests pass. But does it actually work end-to-end? Does the endpoint really return 201? Does the row land in the database? Does the Kafka consumer pick it up? Is the cache written? Is the payment API called with the right payload? Are there stack traces in the logs?
You usually find out later — by hand, or in production.
That gap is the point of noworries. It turns “looks right” into a concrete READY / NOT READY by running the change against real services (not mocks) — and it does this inside the agent’s edit loop, before you review the diff. If it comes back NOT READY, the agent reads the structured failure, edits the code, and runs again, until it’s green.
The honest observation behind the tool: AI produces code fast, but verifying that a change actually works is still slow and manual. Writing code stopped being the bottleneck a while ago. Trusting the change did.
What noworries is
noworries is two things:
- A CLI (
noworries) that reads a declarativenoworries.yml, spins up whatever infrastructure the feature needs in Docker, starts your app wired to it, runs a set of checks against the running system, and reports a single pass/fail result with a structured artifact. - A
/noworriesslash command for Claude Code that ties the loop together: read what changed, generate or update the yml for that change, run the harness, and — if it fails — feed the failure back into the agent so it can fix the code and try again.
It’s written in Rust, ships as a single native binary for macOS, Linux, and Windows, and is MIT-licensed. The only runtime dependency is Docker. Current version: 0.4.0.
The loop
/noworries
1. read what changed (git diff of the agent's edits)
2. write/update noworries.yml (services + checks for this feature)
3. bring up infrastructure (Postgres/MySQL/Mongo/Redis/Kafka/ES, ephemeral)
4. run setup hooks (DB migrations, fixtures)
5. wire and start the app (env pointed at the containers + external services)
6. run the checks (HTTP, DB, queue, cache, gRPC, GraphQL, …)
7. report READY / NOT READY (+ results.json / JUnit / HTML)
8. tear it all down (docker compose down -v, guaranteed)
└─ NOT READY → agent fixes the code and runs again, until green.
Everything is ephemeral. Each run gets an isolated Docker network. Teardown with down -v is guaranteed on success, failure, or Ctrl-C. All configuration lives in a single declarative file.
Here’s a noworries.yml for a small order-creation feature:
yamlversion: 1
services: [postgres:16-alpine, redis]
app:
start: "./mvnw spring-boot:run" # optional; Spring/Go/FastAPI/Node auto-detected
health: "/actuator/health"
checks:
- name: "create order: 201, persists, caches, fast"
request: { method: POST, path: /orders, body: { sku: "ABC", qty: 2 } }
expect: { status: 201, max_ms: 500 }
db: { query: "SELECT status FROM orders WHERE sku='ABC'", expect_row: { status: "PENDING" } }
redis: { key: "cache:order:ABC", expect_exists: true }
A run of that check, when it passes, looks like this:
=== noworries results ===
PASS create order: 201, persist, payment call, log, fast
✓ [http] POST /orders -> 201
✓ [http-latency] 84ms (<= 500ms)
✓ [db] row matched { status: "PENDING" }
✓ [external_calls] payments: 1 matching POST /charge
✓ [logs] "OrderCreated" present; no "ERROR"
Result: READY
=========================
And when it fails, the output is deliberately shaped so an agent can parse it:
=== noworries results ===
FAIL create order: 201, persist, payment call, log, fast
✓ [http] POST /orders -> 201
✗ [db] expected row { status: "PENDING" }, found none
✗ [external_calls] payments: expected 1 POST /charge, got 0
✓ [logs] no "ERROR"
Result: NOT READY
=========================
Every failure carries expected-vs-actual in the JSON artifact next to the human output. That’s what closes the loop — the agent doesn’t need to guess what broke.
What it can verify
Enough breadth that a real feature usually fits inside one file. A short tour:
- Services it stands up: Postgres, MySQL, MongoDB, Redis, Kafka, Elasticsearch (7 and 8).
- Frameworks it auto-detects: Spring Boot, Go, FastAPI (Python), Node.js. If none match, you give it a start command.
- Check / assertion types: HTTP (status, body, latency), SQL (
db,mysql,schema— column/type diffs), NoSQL and cache (mongodb,redis), streaming (kafkaproduce/consume,sse,websocket), search (elastic), APIs (graphql,grpc), observability (metrics/ Prometheus,traces/ OpenTelemetry,logs), contracts (snapshot/ golden diff,external_calls). - Edge-case load scenarios:
burst,concurrent(race conditions),duplicates(idempotency),out_of_order. One-linekind:field, optional throughput threshold. Data paths get tested under load, not only on the happy path. - Flink pipelines: stands up a temporary Flink cluster, compiles and submits your jobs, and verifies Kafka → process → Postgres → topic → Elasticsearch end-to-end.
- External dependencies: either injects the upstream’s sandbox URL and credentials, or spins up an in-process mock that records the outbound calls (assert on them via
external_calls). - Auth, secrets, reports: gitignored
.noworries.env,${VAR}interpolation that refuses to run when required vars are missing,--junitand--htmloutputs for CI.
“The AI can already write Testcontainers tests. Why this?”
This is the first honest objection, and it deserves an honest answer.
They live at different layers. Testcontainers is a library for writing integration tests. noworries is a verification loop for the change the agent just made. They aren’t competitors, and I use both.
The differences that matter in practice:
- No test code to maintain.
noworries.ymlis a declarative file for the change in front of you. Testcontainers gives you container/lifecycle/client/teardown code that lives in the repo, needs upkeep, and can silently rot. And when the AI is writing both the code and the test, “green” doesn’t mean much — the test can be wrong in the same direction as the bug. - Client behavior is solved once. Eventual-consistency retries, Kafka topic auto-creation races, subset matching on JSON bodies, container readiness gates — the harness has those figured out. Every hand-rolled test re-derives them, and re-breaks them.
- Black-box, whole-app, language-agnostic. noworries starts the real app (
mvnw,go run,uvicorn,npm start) and pokes it from the outside. Spring, Go, FastAPI, Node — it doesn’t care. You don’t end up with a different in-process slice-test setup per language. - Designed for the agent loop.
noworries changedscopes to what was touched. The structuredresults.json(expected vs. actual per assertion) is what lets the agent parse a failure and fix itself. That’s the piece that closes the loop, and it’s the part most integration-test setups don’t produce. - Use them together. Testcontainers for the committed regression suite. noworries for the agent’s fast “did my change actually work?” gate.
noworries.ymlis committable, so the same file runs in CI.
Architecture, briefly
For the people who care about the internals:
- Rust, single binary, no runtime to install. Fast startup matters when this runs on every agent iteration.
- Trait-based extension points. Four of them:
ServiceProvider,Framework,EdgeCase,Assertion. Adding a new service, framework, edge-case scenario, or check type is a new file plus one line in a registry — nothing to change in the core. - Plain
docker composeunder the hood, not embedded Testcontainers. That’s why it runs equally well from a shell, from CI, or from a slash command — it doesn’t assume it’s inside a test runner. - The CI runs its own philosophy on itself. Every external dependency (Kafka, Elasticsearch, MySQL, MongoDB, Postgres, Flink) has an integration test against the real service. That’s how a Kafka topic auto-create race and a MongoDB document-nesting bug were caught in the harness itself — the kind of client-library mis-use that unit tests never surface.
What it isn’t
- It doesn’t replace your regression suite. Committed integration tests still matter for the things that shouldn’t break tomorrow.
- It needs Docker running locally. If Docker isn’t there, nothing works.
- The
/noworriesslash-command experience is Claude Code-specific today. The CLI itself runs anywhere. - The tool is early — 0.4.0, actively developed. Some things will change.
Get started
curl -fsSL https://raw.githubusercontent.com/guvense/noworries/main/install.sh | sh
# or: brew install guvense/noworries/noworries
# or: npm install -g @guvenseckin4/noworries
# or: cargo install noworries
noworries install-command # installs the /noworries slash command for Claude Code
Repo, issues, and roadmap: https://github.com/guvense/noworries.
If you try it on a real feature, I’d genuinely like to hear what broke — bug reports and “this assertion type is missing” issues are the fastest way this tool gets better.