Guidelines for Using Pivotal Tracker
July 25, 2016
I am often asked about the meaning of things in Pivotal Tracker, such as “What’s the difference between a bug and a chore?” Or, “How can I tell the difference between a bug and a feature?” Another oldie but a goodie is, “What story should I pick from the backlog?” Here are my biased answers.
A Groomed Backlog is No Substitute for Good Judgement
No matter what you might hope, there is no substitute for good judgement. You should always ask yourself, “What is in the best interest of PacerPro?” If you can’t answer that question, then stop, go find someone who does know before continuing. Great employees will not only do what’s expected of them, but also do what is best for the company.
Tracker Stories Are Focused on Delivering Business Value
Tracker has four and only four types of stories:
A “feature” has quantifiable business value
Here’s my formal definition:
“A feature is a story that was requested by the [client] stakeholder and has quantifiable business value.”
There are some really important concepts to consider here. The story must come from a stakeholder, that is, someone who can make decisions based on business priorities. As a general rule, engineers should not request feature stories, not because they can’t, but because they don’t generally see the business side of things.I don’t keep a lot of secrets. I’ll try to explain the back-story if I can. If everyone knows the business value and complexity of a story, then we can all help ensure that we’re maximizing business value for the company. Let’s be honest, however, stakeholders rarely write good stories, so in general, stories will be written in partnership (pairing) with them. As CTO, I will often trade my engineering hat for a business hat and write feature stories. You may not see the hat switch, but it is there. Ask me, “Which hat are you wearing?” if you are unsure. On the other hand, if you can’t make a judgement based on business priorities, then you shouldn’t be writing stories, either.
The other component of feature stories is that they have quantifiable business value. Stories cost time to deliver. Time that could be spent on other stories. We want to maximize the financial leverage of our work so that we deliver the most value for the least cost. There’s some local maxima at work here, and since our business landscape changes so quickly, we’re only hoping for something measurable in the 90 days after delivery. This is a nod to Pandora’s planning criterion:
“What would be stupid not to do in the next 90 days.”
During planning sessions you may hear me ask the stakeholders, “What’s the business value of this story, in rough dollars?” If all I get in reply is hemming and hawing, I will politely but firmly push back; This story is not ready, or not really that high a priority. There’s an old definition of “urgency,” something that is time critical, but you can have unimportant urgencies. Those stories are not the most important ones to complete. You, as engineers, should know what the quantifiable business value is for a story, and you should ask if you don’t know.Sometimes, we won’t be able to estimate a story’s cost without some research, perhaps some spiking. I’ll break that out into a separate story whose sole output is an estimated cost of the feature.
A “bug” is a defect introduced during the delivery of a feature
Bugs are a drag on velocity.See my earlier article on velocity: “It’s the Volatility that Will Kill You” It slows down our ability to deliver feature stories. There’s really no such thing as zero-defect software and achieving that becomes asymptotically expensive. So we want a process where we minimize bugs for a reasonable expense. That’s why we have tests, continuous integration testing, code quality metrics, quality assurance and multiple staged servers, to name a few. That’s also why we don’t maintain a JIRA installation; it costs more to maintain than we got in reducing our defect rate.
Not all bugs are equal. We prioritize them by business value, too. We can measure value in terms of loss of customers, reduced adoption rate, or even a hit to our brand value. Some bugs are more expensive to fix than others, too. This is one of the pain points of using Pivotal Tracker; there’s no direct way to indicate the cost of fixing the bug. In this respect, in the eyes of Tracker, all bugs are equal. I’ve found this not to be true in real life. Some bugs are easy to fix, or easy to fix right now while we still have context to fix the bug. Bugs to fix in the backlog are in roughly the priority to be fixed, but there’s usually a lot more wiggle room than in feature stories.
A “release” is a time constraint
Tracker doesn’t set many deadlines because most deadlines are bogus. Well, arbitrary. Okay, bullshit. That’s because when they are imposed from above, or don’t reflect any business realities, or don’t adjust to the changing landscape of our business, we’re not maximizing value. And things change, fast. That’s what “agile” means, right? This is not to say that “agile” is an excuse not to deliver on time, either. We want to be realistic about our deliveries. Hence we have “releases.” They can answer two important questions:
- We have an “epic” that must be delivered by an externally imposed date. Will we make it, with confidence?
- How long will an “epic” take to complete? Is the overall cost worth it? Will it impact other commitments?
There are lots of external events that are beyond our direct control: Trade shows, press release dates, legal contracts, holidays, even election day!
Finally, and, least of all
“Chores” are internal stories that must be done, but have no quantifiable business value
Chores are closely related to bugs, in that they don’t have points, so they are also a drag on velocity. Consider them “the cost of doing business.” Where they differ is that chores do not arise as a defect when delivering a feature. They are usually internal engineering work, such as setting up new servers, or renewing an SSL certificate. We also use them as an ad hoc to-do list, e.g. when we need to provision new users for a client. Those requests could be seen as help desk ticketsI need to write a whole other post about help desk operations. , and I may change my mind on this, but for now we’re just going with the flow.
One thing that I am adamantly opposed to are chores to address technical debt. Stories like “code reviews” or “large refactoring.” They are part of our normal story workflow and not an after-thought. If a big refactor is necessary for a story, then so be it. Add that cost to the complexity of the story.See, “Refactoring – Not on the backlog!”
What Should I Do Next?
“The Most Important Thing”
In theory always try to take the next ready story off the top of the backlog. In practice it is not always so simple. It goes back to judgement. Before you click the start button, review the story for readiness and business value. Ask yourself, “Self? Has the business landscape changed since the last time we looked at this story? Is it truly the most important thing to do?” You have the responsibility and authority to “pull the yellow cordA kanban concept. When there is trouble on an assembly line, any worker is empowered to sound an alarm by pulling a bright yellow cord. Anyone available, including managers, rush to the trouble spot to correct the problem and keep the line running. Later, there would be a post mortem to prevent the problem from happening again. .”
(START) => [Started]
Pressing the (Start) button commits you to see the story through delivery and acceptance. You are empowered to choose any solution path that, in your professional judgement, is the most cost effective (in terms of time, resources and maintainability). You are also shielded from working on any other story until the current story is completed (or reasonably blocked).Let’s say that you’ve finished merging and are waiting for CI to deploy to staging for QA. It’s a good time to take a break and celebrate, but if you want to kill off a few Zendesk tickets while you’re waiting, go for it. Just don’t lose track of the main story. There’s ample research that shows that context switching costs more than just doing one thing, well.The True Cost of Multi Tasking, “Psychology Today”, September 18, 2012
When a story gets blocked, you’re first priority is to unblock it. If that’s not possible, add the
blocked tag to the story. Announce that you’re blocked on Slack#engineering. Set a time, at regular intervals, to check up on the blockage. Then, move on to the next story. Announce the blockage at the morning Stand-Up.
(Finish) => [Finished]
Pressing the (Finish) button tells the team that development work is done and that a pull-request is pending on GitHub for review. You can start the pull-request at any time, not just at the end. There is a process pattern where you start the pull-request as soon as you create the story branch. I like it because I get early feedback from CircleCI and CodeClimate. YMMV. Announce the pull-request and ask for feedback. Review criteria will vary, but at a minimum, CI is green, the code adheres to the style-guide (via CodeClimate reports), QA testing on the local development system confirms that the story delivers, in real life, what was originally requested. This is also a good place to show the team the new functionality at the evening Round-Up.
Merge to master, final QA
Once everything is “green,” merge to the master branch (our production ready branch). Re-test the feature on the staging server and run our QA “smoke tests.”We have a small suite of integration tests that can run against a ‘live’ server; either staging or production. These tests assure us that we haven’t broken anything critical and that all services are running properly. You are now ready to deploy to production at your next opportunity. In general, we believe in deploying early and often. Since our deployments do take the background job runner (
Sidekiq) off-line, use your judgement about mid-day (10am Eastern to 6pm Pacific) deploys. Re-run the smoke tests against the production server.
(Deliver) => [Delivered]
Pressing the (Deliver) button informs the team that the story is now live on production. The story requester is responsible for reviewing the feature and accepting or rejecting it. I expect 99% of the stories to be accepted. Rejecting a story at this point is a process fail: Did you include the requester and stakeholders while developing the feature? Did you ask for design and UX feedback? Did you test it so that you were at least 85% confident of success? Was the story truly “done?”
(Accept) => [Done] or
(Reject) => [Unstarted]
Sometimes, we learn things once the feature is live. That’s okay and not an immediate cause for rejection. Rejection is an indication of a process fail, where we did not deliver the story as envisioned, where there was insufficient communication among the team members. Rejection will trigger a post-mortem and a topic for the next retrospective. On the other hand, if we learn something new, then create a new bug or feature story. Remember, “bugs are defects that were created during the delivery of a story.” If the story was delivered properly, but it’s not what’s best for the users, create a new feature story and place it appropriately in the backlog, according to its business value.
What’s in the backlog and the icebox?
The backlog contains stories, prioritized according to release dates and value. While we strive to keep a backlog that will support 2-3 weeks of engineering effort, sometimes we fail. I encourage you to speak up about lingering stories that might become critical in the future. These stories are good to bring up during iteration planning.
The icebox contains stories that have business value in the next 90 days. Everything else isn’t worth keeping. We have a lot of stories with “freezer burn” that I just delete from time to time. You can help by reviewing and tossing the ancient stories.
Shaddup already and let’s get to work!
This has been a much longer rant than I intended, but there’s lots of good stuff here. Many thanks to Rob Mee for his brown bag talk, years ago, that inspired the foundation (and of course, hiring me).