← Daily

Problem breakdown · No. 028 · November 12, 2026

Customers who reported a bug rarely hear when it is fixed

Support links the ticket to an engineering issue, engineering ships the fix, and the customer who reported it is never told. The gap is a missing join between two systems, and one builder can close it.

The problem

A customer reports a bug. The support agent confirms it, links the ticket to an issue in Jira or Linear, tells the customer the team is looking into it, and closes or pends the ticket. Weeks later the fix ships. Nobody goes back to the customer.

The cost is quiet. The customer keeps working around a bug that no longer exists, or writes in again to ask, which creates a new ticket with no memory of the first. Some decide the product does not listen. For accounts that are already at risk, that silence often counts for more than the bug did.

Existing tools only half solve it. Helpdesk and issue tracker integrations can link a ticket to an issue, but the link is optional, so many tickets that describe the same bug are never linked. The tracker's "done" usually means merged, not deployed to the customer's plan or region. And even when the link exists, the follow-up is a manual task that nobody owns.

Constraints

  • Small team: support leads and maybe one engineer who can spare a few days, no ML team.
  • Data lives in two SaaS products with their own APIs, rate limits and webhook quirks.
  • Tickets contain personal data, so any model call needs a vendor agreement and the smallest possible payload.
  • A wrong "this is fixed" message is worse than silence. Trust in the system is the whole product.
  • Support agents will not adopt anything that adds clicks to every ticket.
  • Release information is often scattered across deploy logs, changelogs and feature flags.

System design

The core is a plain link table: ticket_id, issue_id, link_source (human or suggested), confirmed_by, and notified_at. Everything else feeds or reads it.

  • Ingest: helpdesk webhooks for new and updated tickets, tracker webhooks for issue state changes, and a deploy event from CI that lists which issues shipped to which environment.
  • Matching: for tickets tagged as bugs with no link, retrieve candidate open issues by text similarity, then ask an LLM to pick one or none and quote the sentence that justifies it. The suggestion goes to the agent as an internal note with one confirm button. It never writes a link on its own.
  • Fixed detection: deterministic code. An issue counts as fixed only when a deploy event covering the customer's environment arrives. Merged is not enough.
  • Drafting: when an issue is fixed, an LLM turns the technical release note into a short customer-facing reply, one per ticket, using only the ticket's subject and the release note. No dates, no promises, no invented details.
  • Approval: a daily digest per fixed issue lists linked tickets and drafts. A human approves in batch. Sending is idempotent on ticket_id plus issue_id, so a replayed webhook never sends twice.

The model handles fuzzy text: matching and phrasing. Code owns state, timing and sending.

Trade-offs

Human confirmation slows linking and means some tickets will never be matched. I accept that, because a missed follow-up costs what it costs today, while a wrong link sends a false promise.

Depending on deploy events means teams without clean release tracking get less value until they add it. Partial fixes and workarounds are out of scope: they go back to a human.

The batch approval adds a day of latency. Customers who waited weeks will not notice a day.

What I would build first

Start read-only. Pull recent tickets tagged as bugs and the issues they link to, join them against issue completion, and report how many linked tickets never received a reply after their issue closed. That number decides whether the rest is worth building.

Then add the daily digest for already-linked tickets only: issue shipped, here are the tickets, here are draft replies saved as helpdesk drafts. No matching, no automatic sending. If agents send those drafts, add suggested matching next.

When two systems each hold half of a promise to a customer, the fix is an explicit link table with an owner, not a smarter model.