Here at Infinity, one of our core precepts — coined by former Infin-ite Shawn Moore — is the notion that “tickets are free”. The idea is that you should never waste time wondering “should I make a ticket for this?” Instead, just make the damn ticket! In the immortal words of John Blutarsky, “it don’t cost nuthin’.”
With an opening paragraph like that, you’re probably expecting some sort of listicle of all the ways adopting our “tickets are free” credo will help make your software development efforts better and turbocharge your coders to new heights of productivity. That is not what you’re gonna get, however. Nope! Instead, I’m going to talk to you about how tickets are free… because they’re not free like beer, but instead are free like puppies. And then I’ll share ways to make sure your freely created tickets are usefully propelling your project forward, instead of bogging it down.
If you’ve never raised a puppy you might be thinking, “what’s the problem with free like puppies?” The problem is that puppies, while generally wonderful and cute, also represent an ongoing obligation. You’ve got to walk them, feed them, get them socialized to being around people and other dogs, and most importantly, you need to train them, so your puppies grow up to be good doggos. What I’ve been slowly realizing, over several years writing code and providing technical leadership in projects that adhere to a “tickets are free” approach is that, unless you’re disciplined — much like you have to be disciplined when raising and training a puppy — “tickets are free” can lead to a massive backlog of unactionable, low-quality tickets.
big smelly backlogs
To me, a large backlog of open, stale tickets that aren’t ever going to be acted on is a huge project smell. It’s a sign the project isn’t being effectively managed. When I see this in the bug tracker for an open source project, or even a commercial product, I tend to shy away from using that software. A large unmaintained backlog gives me the impression that the folks running the project have given up and just don’t care anymore. It’s not unlike the signal you send to your neighbors when you have a rusted out, half-built kit car up on blocks in your yard.
Don’t get me wrong. We still frequently say, “tickets are free” here
at Infinity. We’ve had cases where the notion of free tickets has
absolutely saved us from shipping bugs. When we bring somebody new on
to a project, it is among the very earliest things we’ll tell them
about how we work: when you think about making a ticket, make a
ticket, right then. Particularly if you’re in the middle of working on
something else, like trying to chase down a bug, or trying to finish
implementing a feature. When you’re in that focused zone, and hit some
sort of pothole or speedbump, don’t break focus, don’t try to figure
it out right then — but do make a ticket. Tickets, after all, are
free! If it turns out that the ticket isn’t needed — maybe you
misunderstood how something was meant to work or maybe the ticket
duplicates another existing ticket — closing a ticket as
DUPE is easy.
Where the cost of those “free” tickets shows up is that someone needs to be cleaning up after the tickets — just like you have to clean up after puppies. Particularly if you’re making it in the heat of the moment, in the middle of doing something else, you’re probably not going to produce a fully-baked, ready-to-work-on ticket. And that’s okay! At that point, simply capturing the idea so it doesn’t get lost is the objective. But in order to fully close the loop and realize the value of your free ticket, somebody on the project team needs to be routinely examining the backlog and making sure all the tickets in there are “good” and ready for somebody to start working on them — and if they’re not, that person should be working with the ticket creator to get them into that state.
good tickets are smart
So, what exactly makes a ticket “good”? Ultimately, the goal of a ticket is to be closed — a good ticket is a closable ticket. I contend that a good ticket takes the form of a SMART goal. If you haven’t run across the acronym before, SMART stands for Specific, Measurable, Actionable, Realistic, and Timebound — all attributes of good, closable tickets.
Good tickets should be specific: if the ticket describes a feature
to be added or a task to be completed, it should contain enough
information about that task or feature that the person the ticket is
assigned to doesn’t need any additional information in order to write
the code implementing that feature. If the ticket describes a bug, it
should explain the observed behavior of the software, what the
expected behavior of the software is, and include the steps necessary
to recreate the bug. If either of these conditions isn’t met, it’s
likely that the ticket isn’t specific enough for the assigned person
to be able to do the work to close it, and more information needs to
be added to the ticket. Don’t be vague. For example, don’t tell a
programmer to make the
H1 font “the other blue.” Instead, tell them to
H1 font to
Good tickets should be measurable: any quantities, timings, or metrics in the ticket should be explicitly spelled out. For example, “support concurrency” or “reduce application latency”, are both bad tickets: how is a programmer supposed to know when they’re done? Instead, you need to specify the number of concurrent users, or an upper bound on the acceptable latency of the application.
Good tickets need to be actionable: tickets should be written so that the summary is a short, directive sentence using an action verb and a target noun, such as “Add ‘create account’ button to login modal” or “Increase cache size to 1024MB”. Avoid ticket summaries that contain questions or offer an opinion, like “Should login modal default button be ‘login’ or ‘create account’?” or “I think we should have a bigger cache”. Either save those questions for a standup meeting, or create an actionable ticket for yourself, such as “Discuss login modal default button”. (When tickets are free, tickets frequently lead to the spawning of other tickets…)
Good tickets need to be realistic: generally, when folks create unrealistic tickets, it’s because they’re making tickets that are unrealistically large. (This can be a side effect of the ticket being nonspecific or unquantified.) Generally speaking, on a quickly-iterating project with a team of developers all working simultaneously, a properly-sized ticket is one where the developer working on it can complete their work and submit a pull request within a day or two at most — ideally in under a day. If their work takes longer than that, the chances of a merge conflict occurring when the developer attempts to bring their long-running branch back into the common code base start to rapidly increase.
Finally, good tickets need to be time-bound: project managers and developers should have an understanding about how long a particular ticket will take to complete. Having developers estimate how long it will take to complete a ticket, and then tracking how long it did take to complete the ticket, is a great way to practice estimation skills. Tickets where a developer is unable to commit to a deadline, or where a developer keeps missing a deadline, may represent cases of tickets that were nonspecific or not written in an actionable way, requiring the developer to commit to more work than they expected.
the pragmatic tl;dr
On a practical level, when I’m making new tickets, I try to follow just a few primary guidelines:
- Every ticket must contain the answer to the question, “when can this ticket be closed?”
- For task or feature tickets, the ticket summary should be a short sentence using an action verb.
- For bug tickets, the ticket summary should be a short sentence describing what should happen
Finally, to summarize:
- Puppies are good
- Keep your tickets as free as possible
- Make sure your tickets are SMART
Thanks for reading my thoughts on this subject. If you’d like to discuss, feel free to reach out to me on Twitter or via email.
Tags: culture communication