One button, five jobs
Whoever is giving the feedback, the trouble is the same: it arrives missing the one detail you need, and getting it costs another round of questions. Here's what changes when they can point at the problem instead.
Vibe coding is fast. Cleaning up after it isn’t.
You ask an agent to fix one button. It fixes a different button that matched the description. It rewrites the whole file to change one line, and drops the error handling on the way. It gets a failing test to pass by loosening the test. It calls a function that doesn’t exist. Then it tells you, with total confidence: fixed, all tests green, verified in the browser. It never opened a browser.
Each of those is small. Together they’re why a vibe-coded app looks fine in the demo and falls apart in use. A user finds the regression three days later, forty agent commits on, and nobody knows which one did it. The fix for B brings back A. The bug you fixed on Monday is back on Thursday, because the agent forgot why the code was there.
Reading the diff doesn’t catch most of it. The diff looks plausible: that’s what these models are good at. What catches it is someone using the real page.
quibble doesn’t review code, and it won’t make an agent honest. It makes the running app the judge. Use the build, point at whatever’s wrong, and the issue records what the browser actually saw: the page, the exact element, the errors it threw and, if your app adds it, the build it was on.
- The right button, not a similar one. The issue names the element you pointed at, so “the export button” can’t be read as a different one.
- “Fixed” is checked by the page, not the agent. Still broken? Point again. The new note carries the new build, and the old “fixed” stays on record.
- Regressions with an address. Point at what broke since. The page, element, error and build tell you where to look and when it started, instead of “something’s off”.
- A record of claims against reality. What the agent said it did sits in your tracker next to what the browser showed.
- Put quibble on the build your agent works on: inside your app, or as a companion on your computer with
quibble serve. - Use it like a user. Point at whatever’s wrong; your agent picks the issue up from the
quibblelabel (Claude Code, Copilot’s coding agent, Codex or any agent that reads your tracker). - When it says “fixed”, check the page, not the summary. Point again at anything it got wrong or broke.
What changes: you stop merging on the agent’s word. Every “fixed” is checked against the running app, and every side effect lands as an issue with the evidence attached, before a user finds it.
#418 Q3 report: Since the fix for #412, the totals row is gone
P1regression
- Page: /reports?id=7
- element: table.report tfoot tr.totals
- build: 4f2c9e1
- Reported by: [email protected] (via quibble)
▸ Diagnostics jsErrors: TypeError: totals is undefined (/static/report.js:88:14)
Your users found the bug. They just didn’t tell you.
Most people who hit a problem don’t report it. They retry, work around it, or leave. You see it later as a dip in a chart, with no idea which page or which button. The ones who do write in are already annoyed, and they describe the symptom, not the cause: “the export doesn’t work”, “it logged me out again”. It happens on their phone, on one page, some of the time.
So the issue sits at “needs info”. You reply asking which page, which browser, could they send a screenshot. Two days later they answer half of it, or nothing. Meanwhile three more people hit the same thing and said nothing at all. The bugs that hurt most are the intermittent ones, and those are exactly the ones an email can’t capture.
Asking users to report better doesn’t work. Reporting has to cost less than putting up with the problem, and the evidence has to be captured for them, at the moment it happens.
quibble can’t make anyone report, and it can’t reproduce a bug for you. It makes reporting a click and a sentence, on the page where it went wrong, and records what the browser saw at that moment.
- Evidence from the moment it happened. The page, their screen size and browser, and the last errors the page threw. The intermittent ones arrive with what you’d never get by email.
- Who it was, without a form. From the sign-in your app already has, so you can follow up with the right person.
- On your terms. Only the tags you already use, and priorities on your scale. An annoyed user can’t file a P0 called “urgent-customer-facing”.
- Next to the rest of your work. In your tracker, not a separate inbox nobody checks.
- A developer adds the button once.
- Your users click what annoys them and write a sentence.
- It lands in your backlog with the page, their browser, the error and who sent it.
What changes: the backlog reflects what users actually hit, and “needs info” stops being where bugs go to die.
quibble’s endpoint sits behind your app’s sign-in, like the rest of your app. It is for people who use your product, not an open form on a public page.
#218 Checkout: The coupon box says every code is invalid
P2checkout
- Page: /checkout
- Reported by: [email protected] (via quibble)
- viewport: 390x844
Five reviewers, three versions, one launch date
Before a site goes live, the client, the copywriter, the brand team and legal all read it. Their notes arrive as annotated screenshots, PDF markups, emails and a chat thread: “the second paragraph on the pricing page”, “make the logo pop”, “see my earlier comment”.
Some of it is about last week’s version. Two reviewers contradict each other, and neither knows. A fix looked right on your laptop and broke on a phone. Somebody’s “approved” was a reply-all you missed. The night before launch you’re comparing screenshots against the live page to work out what’s been done, and the comment you were afraid of missing is the one that goes live.
The problem isn’t the feedback. It’s that the feedback has no address: no page, no element, no screen size, and nowhere to mark it done.
quibble doesn’t settle arguments between reviewers. It gives every comment an address and a status. Reviewers click the heading, image or link they mean and write a sentence.
- The exact part. The element they clicked, not “the heading”.
- Phone or laptop. The screen size is in every note, so the phone-only problems say so.
- Contradictions side by side. Who said what about which element, in one tracker, instead of scattered across threads.
- Done means closed. Every comment is an issue. Launch when the list is empty.
- Put the button on the review copy, or have your own team use the browser extension, with nothing added to the site.
- Reviewers click what they mean and write a sentence.
- Work through the issues, and launch when they’re closed.
What changes: launch day is a list of closed issues, not a night of comparing screenshots.
The button needs a Python backend: for a static site, serve the review copy from a small Python app that mounts quibble (four steps), behind your sign-in. The live site doesn’t carry it. The browser extension needs nothing on the site, and files to GitHub from Chrome or Brave.
#57 Pricing: This still says 2025
P2copy
- Page: /pricing
- element: h1 “Simple pricing for 2025”
- Reported by: [email protected] (via quibble)
- viewport: 390x844
“Can’t reproduce.” Closed.
Writing up a bug can take as long as finding it: the steps, the browser, the console, a screenshot, copied into the tracker by hand. Under a deadline the write-ups get shorter, and the details that mattered are the ones left out.
Then it bounces: “can’t reproduce”, closed. It only happens in Safari at phone width, on the build before last, after a failed request the tester never saw. Two releases later the same bug is back, and nobody can say when it returned or whether it was ever really fixed. So testers stop filing the small ones.
The details that make a bug reproducible are the ones a person doesn’t think to copy: the failed request, the console line, the exact build.
quibble can’t find bugs. It captures those details at the click, so the write-up is the tester’s sentence and everything else is attached. Testers can point at the element and attach a screenshot too.
- The environment. Page, browser, screen size, language and time zone, every time.
- What went wrong underneath. The last errors the page threw, plus failed network requests and console output once you turn them on for a test build.
- The build. Add your own fields, such as the build number, to every note.
- The history. Each note goes to the right repository by the page it came from, and the review page lists everything filed, open or closed, so a bug that’s back sits next to the one that was closed.
- Add quibble to the test build.
- Testers click what’s broken and write a sentence.
- Developers get issues they can reproduce.
What changes: bugs arrive reproducible, testers file the small ones again, and “can’t reproduce” stops being a way to close a ticket.
#57 Profile: Save spins forever on the profile form
P1bug
- Page: /settings/profile
- build: 2026.09.24-rc2
- element: form#profile button[type=submit]
▸ Diagnostics netFailures: POST /api/profile → 500 (812ms)
Three emails to learn which page they were on
A customer is stuck. They write “it’s not working”. Your first reply is questions: which page, which account, what did the error say? They answer tomorrow, and only half of it. By the third email they’re angry, and some don’t send a third email. They cancel.
The helpful ones send a screenshot, with their card number, their address or someone else’s data in it. Now it’s in an inbox, a helpdesk and a backup, where it should never have been. And when it turns out to be a real bug, someone copies it into the tracker by hand, and the details get lost again.
Support isn’t slow because the team is slow. It’s slow because every conversation starts by gathering facts the browser already had.
quibble isn’t a helpdesk, and it won’t answer customers for you. It lets them ask from the page they’re stuck on, in a sentence, and hands your team the facts first.
- The facts first. The page, who’s asking (from your sign-in), the error the page showed, and account details your app adds, such as plan or account ID.
- Private stays private. Mark the card form private and it’s blanked out of any screenshot before it leaves the browser. If quibble can’t be sure where it is, it doesn’t take the screenshot.
- One place. The request is already an issue, next to the fix it leads to. Nothing to copy across.
- Add the help button to your app.
- Customers ask from the page they’re stuck on.
- Your team answers with everything already in hand.
What changes: the first reply is the answer, and nobody’s card number ends up in your inbox.
quibble files into your issue tracker, not a helpdesk. It suits teams that run support from GitHub, GitLab, Gitea, Forgejo, Jira or Linear, next to the fixes it leads to.
#731 Billing: I can't update my card, it just says something went wrong
P2billing
- Page: /settings/billing
- Reported by: [email protected] (via quibble)
- account_id: acct_2231
- plan: Team
▸ Diagnostics jsErrors: PaymentsError: card update rejected (code PM_402)
Start with the one that hurts most
quibble is in early access, and free for small companies. Send an email to hello [at] quibble [dot] fyi and say which job you have in mind.