Let's pretend you, a programmer, have been given this task:

Display Subtotal to the Customer

The task may sound like a valid request on first read, but I have a ton of questions:

  • What subtotal are we displaying?
  • Who is the customer?
  • Where are we displaying this new piece of information?
  • How is the new subtotal value calculated?
  • Does my team own this value to calculate this new subtotal field, or do we get it from some other team?
  • Where do we get the customer information?
  • If we're integrating with some other team for some of this data, what are their APIs? How do we get data from them? How do we send data to them?

The original ticket was just an idea. It lacked the depth we'd need to perform the task. I hate this with a passion. In my ideal world, all the questions would be answered up front, and by the time we get to implementing the ticket, all doubt is removed and we're off to the races, coding like mad.

I've been able to institute a procedure at the day job to help get better, more detailed, tickets. Over the years we've tweaked this and it works well. Want to know how? Read on and I'll tell you about our process in this post.

The Idea

At some point, someone is going to have an idea for the next feature you build. Ideas can come from anywhere:

  • Product Owner: A Product Owner is the most common person to bring new initiatives to our team. These are usually brand-new business drive initiatives that evolve our systems to add more features in order to support long term business goals, or Key Performance Indicators (KPI). This is where the team spends most of their time working.
  • The Developers: A developer can propose an idea. These are often referred to as tech driven initiatives, or TDI. They often focus on improving the stability, flexibility, maintainability or architecture of the code base, and less on user features. We call these Ops Backlog tickets, and try to fit at least one each sprint.
  • Team Leads: A team leader, such as an Engineering Manager or a scrum master can recommend new features. Sometimes these come from speaking to the developers and get classified as TDI, but sometimes they can be usability improvements from using the system. Sometimes they may be brand new ideas.
  • Designer: A Designer may raise-up issues with the usability of the interface. These are often tweaks that they believe will improve the usability, or experience, of our applications.
  • Other Teams: Other teams, often those who we have integration points with, will sometimes reach out and make requests for us to evolve our system in order to support their business needs. Sometimes this happens through each team's respective product owners chatting with each other. Other times it happens from developer to developer and bubbles up.

Whoever has the idea, we try to get them to take up the steps to write up a ticket for smaller initiatives, or a product brief for larger initiatives. The focus of this article is all about larger initiatives. The product brief will include details of the business value of this new feature and a list of problems we are trying to solve. The business case is so we can sell it to leadership as something important we want to build. The list of requirements documents the criteria used to define success in our implementation.

In my current environment, many initiatives will often involve multiple teams working together, so the product brief can be shared across teams so that we are all working together on the same goal.

The Design

After the product requirements are collected and documented, our design team will start talking to users about this change. Sometimes they'll create user personas. Eventually, they'll create some design mocks, and document user flows. Sometimes they'll run usability studies based on the early designs.

When early designs are created, the design mocks are discussed with the developers and other stakeholders. This will help solidify requirements that feed into our software architecture and UI Implementation.

The Intake

While the Designer is working on the design side of things, a leader on the team--usually the manager--will start an intake process. This is where I am most involved in the process. They document all the relevant things from the requirements that relate to our team. Here are some common things:

  • Are there important requirements that relate to our team's implementation? What are they?
  • Does our UI Require Changes? If so, what? Has our designer started working on this yet? Are there designs we can link to?
  • Do our services require changes to support this new initiative? Do we know what they are yet?
  • Do we have integration points with other teams? Will we be using existing systems / APIs, or creating new systems to communicate between the teams? Is there a shared data schema that needs modification? Who is the primary contact on the external teams?
  • What are the company deadlines, if known? What is the availability of other teams to engage us on this project?
I try hard not to be prescriptive in the implementation at this stage, because I think that responsibility should fall onto the developer team. I may include a high-level architecture diagram of the data flow through respective systems, even if I don't document individual APIs or share data schema.

The Research Spike

Now it is time for the developers to get involved. One of the team will take on a research project within our sprint, becoming the lead developer for this initiative. Sometimes these spikes are left for standard picking; other times the team leader will ask one of the devs to take it in advance.

The lead developer will read all the requirements and the intake doc. They'll review the designs from the designer and determine how they mesh with requirements. They'll reach out to other teams that we have integration points with. All of this will help them determine an approach for making changes to our systems.

They dev will write up a document for the other devs, which we call a Request for Comment (RFC) doc. It will include:

  • Business Case: Summary of the initiative, and he business value behind it.
  • Integration Points: A list of integration points and requests we're making for downstream teams. This may be a change in our shared schema, or a request for an API change from other teams. We often try to get this section written up first, so we can get buy-in from our teams.
  • Auth Changes: Do we need to set up new users to the application? Will we need new security groups, or roles? Are there new permissions needed to expose this functionality? Will other engineering teams need a machine user?
  • Service Changes: How does our service layer need to change to support this new initiative? How does our database change? Are we building new APIs, new database tables? Or are we changing existing tables?
  • UI Changes: What are the UI Change that happen to make this new initiative work? Are we building new screens? Do we need proxy endpoints in our NGINX Config? Do we need new tokens to access new systems?

For many of these items, the developer may think up more than one option. In which case the developer will describe the option, and weigh the pros and cons of each option, along with their preferred recommendation.

The spike ticket responsibility is shared among all team members, not just the more experienced developers. This helps give less experienced devs the opportunity to lead a project, to grow their architecture skills, and to think about building something for the long term. This type of work can also be used to create shared ownership of our domain and bolster a promotion case, to prove that these devs are working at the next level.

RFC Review

After the RFC is written, the team discusses. I like to split this up into two meetings, a silent read out meeting and a decision meeting.:

Silent Read Out and Debate

This is the longer meeting. We usually start with a half hour silent read of the RFC. At this time people will put comments on the RFC, and ask questions. Then, the team will go over the comments, and debate the approaches. Sometimes a new approach is introduced, sometimes a hybrid between the proposed options, and sometimes something completely new.

I like to think of these meetings as war room meetings. You come in, ready to argue for your desired architecture. Draw a line in the sand and prove to everyone else why you think this is best. Be stubborn.

On the other hand, a war room is not always the best stance to friendly debate, so I caution about allowing toxicity to rule. We want friendly debate, even when the opinions are strong.

After the debate, we break. Sometimes, the RFC Writer will need to take some time to write up new options or change the recommendation.

Decision Meeting

After we have some time to sleep on it, I like a second meeting to make the decisions. This is less about the debate, and more about decision. We've all made our case, so now can we all align on a path forward?

When it comes to architecture decisions, I only get my way about half the time, but I've still been able to build great things with a supportive, collaborative team.

Ticketing

After we determine a path forward, architecture wise, it is the developer's responsibility to write the tickets. My own personal philosophy is that our architecture should be planned in advance. When we get to the implementation phase, we're just grabbing tickets and running with them.

We try to make tickets as small as possible, which allows us to often do work in parallel. Small tickets also have smaller PRs which are easier to review, and quicker to merge, and quicker to unblock the next the next dependency.

Writing tickets can take time. There needs to be a balance between descriptive tickets that allow the developers to build easily, and prescriptive tickets that just tell the developer what to do. Ideally, we want to be more descriptive, and less prescriptive. A ticket should not remove developer autonomy, and I find that the more prescriptive the ticket is, the harder it is to write. I've joked that if you only need another five minutes to finish the ticket after writing it up; you have included way too much detail. There is a balance and mastering that balance has proven challenging for us as a team.

JIRA does an okay job of tracking dependencies, however as a team we've started using LucidChart, a diagramming tool, to show all the ticket Dependencies, including those on external teams. It is an easy way, at a glance, to see a visual representation of all the tickets in the initiative, and what is next. Our scrum master will often use this doc to fill out tickets for the next sprint. The devs will use this to choose the next ticket when they complete something early.

Pre-Refinement

After all the tickets are written and documented we do something that we call pre-refinement. This is an engineering manager or technical project manager, the RFC Writer, and one of the experienced developers on the team. The RFC Lead will walk-through the tickets, and explain the purpose of each one. The rest of us will read the tech details and acceptance criteria. We'll validate that they make sense on the context of the larger initiative and look for any blind spots. Sometimes we may suggest splitting up larger tickets into smaller ones; or combining related tickets back into one.

This is often a great opportunity for a more senior member of the team to mentor a junior member of the team on skills beyond code.

Backlog Refinement

Finally, we're ready for the team to point the tickets. I'll have the RFC Writer step us through ticket requirements and tech details, and the team will ask questions and pick points using our normal planning poker approach. We'll debate points if there are discrepancy, often comparing tickets relative to each other.

In most cases, this is less about changing the tickets and more about the full team understanding the thing we're going to build and how we're going to build it.

Build It!

After all the tickets are pointed, the team will start our development process. Tickets are brought into a sprint based on precedence, team capacity, and dependency chains. The tickets are detailed, and the devs can speed run through the development.

Final Thoughts

No process is perfect, and this has helped my team build great things over time. The process, although complex, is based on my own belief that a minute in planning can be worth an hour in implementation. This doesn't mean our tickets cover every possibility, or that we don't make mistakes. Nothing is perfect. When mistakes happen, we adjust. This may mean creating more tickets or changing tech details on an existing ticket. After all, Agile is supposed to be about flexibility of the process.