The Ticket That Kept Working After It Was Closed

In 2019, a mid-sized SaaS company running a project management tool for construction firms found itself with a peculiar problem. Their engineering team was, by any dashboard metric, extremely productive. Tickets were getting closed. Velocity was up. Sprint reviews looked clean. And yet, the product kept regressing. Features that were marked resolved kept coming back broken. Customer complaints clustered around work that had, officially, been finished weeks earlier.

The engineering manager, trying to diagnose the issue, pulled the ticket history for a handful of these recurring regressions. What she found wasn’t a testing problem, or a deployment problem, or even a communication problem in the conventional sense. It was something more fundamental: her team had developed a tacit habit of closing tickets the moment the immediate work was done, rather than when the task itself was done.

The distinction sounds pedantic. It isn’t.

What Was Actually Happening

Here’s a concrete example from their codebase. A ticket comes in: “Date picker in project timeline breaks on Safari 12.” A developer investigates, finds a CSS flexbox rendering quirk, writes a fix, opens a pull request, gets it merged. Closes the ticket. Done.

Except: the fix introduced a subtle layout shift in Chrome on Windows. The developer didn’t check that because the ticket said Safari. There was no documentation update to the component’s known-quirks section (yes, they had one; no, it didn’t matter if no one updated it). The QA checklist for that component wasn’t revised to include a cross-browser smoke test. And the customer who filed the original complaint was never notified, so they found out the fix existed by accidentally noticing the bug was gone.

Four separate threads of work were implicitly part of that ticket. One of them got done. The ticket got closed.

This pattern, repeated across dozens of tickets per sprint, created a kind of technical and operational debt that didn’t show up in any standard metric. It wasn’t quite technical debt in the code sense. It was closure debt: the accumulating gap between “the immediate work is complete” and “this thing is actually finished.”

Spectrum diagram showing the gap between completing primary work and fully closing a task
Most teams operate somewhere in the left third of this spectrum and call it done.

The engineering manager eventually ran a retrospective exercise where she asked developers to list, for a recently closed ticket, every downstream action that should have happened before closing it. The average list had six items. The average number of those items that had actually occurred was two.

This wasn’t laziness. The developers weren’t cutting corners. They were operating under a mental model that equated “the code is merged” with “the task is done.” That model was invisible to them because no one had ever articulated a different one.

Why This Pattern Is Everywhere

Software teams are an easy case study because their work is unusually legible. Tickets, commits, pull requests, deploys: there’s a paper trail. But the same gap shows up in product teams, in marketing, in operations, in any knowledge-work context where tasks have both a visible output and a set of invisible downstream responsibilities.

The psychological mechanism is well-documented in the productivity literature. Completing the core action of a task (writing the code, sending the email, publishing the post) provides a closure signal that makes the surrounding obligations feel optional or secondary. The brain marks the item as resolved. The remaining steps have to fight against that resolution signal to get done, and they usually lose.

This is partly why to-do lists fail so often as productivity systems. A to-do item like “fix date picker bug” is a container that can hold anywhere from one to ten distinct actions, and the system treats it as a single binary: done or not done. The moment you do the most salient action inside the container, the whole container feels done. Notifications have the same problem: closing the alert and handling the underlying issue are two different cognitive events, but we tend to conflate them.

There’s also an organizational pressure component. In sprint-based development, there’s real social friction around carrying tickets past a sprint boundary. Closing things feels like progress. Open tickets feel like failure. That pressure is legitimate in some ways, but it trains people to optimize for the closed state rather than the finished state.

What the Team Actually Did

The engineering manager’s first instinct was to add a checklist to every ticket. That’s the obvious solution and it’s mostly wrong, for the same reason code coverage metrics are mostly wrong: people will game the number. A mandatory checklist gets check-boxed, not completed.

Instead, she did two things. First, she made a small but significant language change in how the team talked about work. “Closing” a ticket became a distinct act from “finishing” it. Finishing meant the code was merged and working. Closing meant every downstream action had been addressed or explicitly deferred with a reason. The sprint board had two columns that had previously been merged: “Dev Complete” and “Closed.” She separated them.

Second, and more durably, she introduced what she called a “closure definition” at the ticket-writing stage rather than the closing stage. When a ticket was created, whoever wrote it was responsible for listing the non-obvious things that would need to happen for the task to be genuinely complete. Not a generic checklist, but task-specific. The date picker ticket would have had, in its original text: “Verify fix in Chrome/Windows, update component quirks doc, notify original customer.”

This shifted the overhead to the front of the task rather than the back. Cognitively, that’s a much better time to enumerate closure requirements: you’re thinking about the problem space anyway, and you haven’t yet generated the false closure signal that comes from doing the primary work.

Six months later, their regression rate on “fixed” issues had dropped noticeably, and the customer notification lag (time between a bug fix and the reporting customer being told about it) dropped from a median of three weeks to under two days. Not because they hired more people or changed their tech stack, but because they stopped conflating two things that were never the same.

What to Take From This

The lesson isn’t that you need better checklists or a new project management tool. Those are solutions looking for a problem statement. The actual insight is narrower and more actionable.

Finishing a task is a technical event. Closing a task is a social and systemic one. The code is either merged or it isn’t. But “closed” means: all stakeholders are in the right state, all documentation reflects reality, all downstream systems have been updated, and all implicit obligations have been discharged or consciously deferred.

When you write a task (for yourself or for someone else), the moment to think about closure requirements is not when you’re about to mark it done. It’s when you’re writing it. Ask: what does “actually finished” look like for this specific thing, as opposed to “the main work is done”? Write that down. The difference between those two descriptions is your closure debt in advance, and it’s much cheaper to pay it then than to rediscover it three weeks later when a customer files a regression.

The deeper point is about honesty in how we represent work. A closed ticket is a claim that something is done. If the definition of “done” is fuzzy or implicitly narrow, that claim is false in a way that will eventually cost you. Making the definition explicit, even briefly, is how you make the claim true.