From Chaos to Clarity: Shaping Effective Ways of Working in Engineering Teams
In this blog, I navigate the challenges of managing diverse engineering teams with operational freedom, and share our 'Ways of Working' template so you can do the same.
When I joined Personio as a product manager in 2022, one thing that struck me was how differently every engineering team managed their workloads, and the freedom each team was given to self-organize.
“Your team is working on a greenfield project and you want to work in Kanban? Fine!”
“You’ve now moved into a more regular development cycle and wish to switch to Scrum? Do it!”
Teams are allowed to design a way of working that best suited their scenario and the individuals on the project they were running, enabling them to be truly agile.
But this flexibility can have a downside, too. In this article, I will explain the challenges that came with this operational freedom and how I attempted to tackle it on the teams I manage. I will also provide you with a template that you can use if you are trying to solve some of the same issues I describe below.
Dynamic engineering teams at Personio
Personio is one of the fastest-growing companies in Europe, which means our teams are scaling in size quickly, and we aim to have them deliver impactful features at a fast pace to our customers. This leads to Personio’s engineering teams working very dynamically, with the regular occurrence of teams growing and splitting to focus on new projects.
One side effect of this dynamic environment is that new members need to be onboarded to these new projects frequently and with that they need to learn this new team’s particular ways of working. During this onboarding, information can be missed, causing friction for the new joiner until they can get up to speed on how this team actually works to deliver their features.
To mitigate these issues, I worked on creating detailed Ways of Working for the teams I manage in my Tribe. Every aspect of our engineering team’s daily duties are taken into account and decided upon together, removing any ambiguity around how something is done.
If a new issue arises that isn’t on the list yet, we simply go through a review process like any normal merge request and decide as a team on the new lines or sections to add to our Ways of Working.
Ways of Working template
Note: As this is a template, I have removed my own links below. Anywhere with the annotation <Link> is a place you should add your own internal link.
Jira hygiene
To ensure consistency and avoid confusion or overlap, we have a base Jira hygiene for all issues.
Tickets begin their journey as Triage, and must meet certain criteria before moving into the backlog and onto a sprint.
Each issue must contain a “Description”, “Acceptance Criteria” and, when requested, additional “Technical Implementation” details for more complex issues. Tickets will remain in Triage state and should not be estimated until these criteria have been met.
Once a ticket has its story points estimated, it can be moved to the backlog state or into “selected for development” on a sprint.
Issues will be assigned to Epics (List of Epics here<Link>, future Epics here<Link>). If no Epics are deemed suitable, the EM or PM will be notified and create a new one, or find a good home for the issue. Epics must have a clear definition of “Done”, and the Epic cannot be closed until the tasks in the Epic fulfill this definition of “Done”. If there are questions about the clarity of the Epic DOD, this should be raised in any of the regular refinement meetings.
Issues will be labeled with one of the following big rock labels:
PROJECT_TECHDEBT
PROJECT_MVP
PROJECT_FEATURE1
PROJECT_FEATURE2
PROJECT_SLO
PROJECT_ADOPTERS
PROJECT_FEATURE3
The EM and PM will be regularly monitoring the issues: (<Link> to tickets without labels) or (<Link> to tickets without parents). They will contact individuals when necessary to ask where the issue should go.
Tech debt stands for anything that is not related to the initial deliverable of the big rock. Once the MVP of a big rock is completed, anything else related to the MVP would be considered tech debt, unless it is part of one of the other big rocks or a new big rock.
Issues should not be assigned to Epics or Initiatives that have been completed or closed.
Priorities will be assigned to issues based on the team’s feelings about the priority, compared to the other issues they have completed.
Spike tickets
Spike tickets can be estimated or time boxed to a certain size when estimations cannot be made. Every spike should follow the following construct:
1) Clear objective
State the clear objective or purpose of the spike, such as “Investigate the feasibility of implementing feature X” or “Research potential solutions for performance optimization.”
2) Deliverables
Specify the expected deliverables or outcomes of the spike. This could include documentation, Jira Tickets, recommendations, prototype code, research findings, or proof-of-concept implementations.
3) Success criteria
Define success criteria or measurable indicators that will determine the completion of the spike. These could be specific milestones, benchmarks, thresholds that need to be met, or refined tickets that can go for grooming.
4) Communication
Clarify how the findings or outcomes of the spike should be communicated, such as through a presentation, report, or documentation shared with the team.
5) Next steps
Outline the expected next steps based on the findings of the spike. This could include recommendations for further action, potential implementation approaches, or decisions on whether to proceed with the feature or optimization.
Story points
Story points are used to measure the complexity of an issue. The team’s story points are based on their individual feelings, and cannot be compared to story points from other teams in the tribe.
Issues should be sized using Fibonacci sizes, i.e. 1,2,3,5,8,13, and so on.
Parabol is used for sprint poker. If not using parabol and using sizing in the meeting, we should attempt to input the scores at the same time to avoid bias. For example, the person leading the meeting could say “1, 2, 3, input.”
1 story point is considered to be the smallest piece of work that can be done on an issue. Larger story points are not based on time, but rather complexity when compared to a 1 story point issue.
1 story point ticket examples:
<Link> 1
<Link> 2
<Link> 3
2 story point ticket examples:
<Link> 1
<Link> 2
<Link> 3
3 story point ticket examples:
<Link> 1
<Link> 2
<Link> 3
We do not allow issues to be greater than 5 story points. Where possible, 5 story point issues will also be broken down into smaller issues. Estimations should be given in the designated post-daily standup refinement time slot.
We should only story point issues when more than one engineer is available. In a case when only half the team is available (e.g. two out of four) and more members will not return before the issue is due to start, we can size but will inform the missing members to provide their feedback on their return in one of the team’s scheduled meetings or in Slack, depending on preference.
If a disagreement occurs on an issue’s story points, we should discuss the highs and lows to understand the underlying reasons behind the points given. If there is still no agreement, we should revote. Optional alternatives:
If the votes still don’t match, but are consequent numbers (2,2,2,3,3,3), then we will take the higher number. We should not waste time on this discussion if the sizes are similar.
If the team is tight on time and needs to refine multiple tickets, we’ll skip the above step and pick the higher number.
Standups, coworking and refinement sessions
We have 15-minute daily standups every weekday except for Wednesday, our no-meeting time-for-focused-work day, as well as 45-minute coworking meetings every weekday except for Wednesday. These coworking times can also be used for refining tickets or for discussing any topics, tickets or learnings that the proposer would like to discuss in person.
Coworking happens directly after the standup on Monday and Friday, using the regular standup Zoom link. On Tuesday and Thursday, coworking is at 3pm CET with its own Zoom link. Attendance for these coworking sessions is optional, unless you are part of the suggested audience to the topics or refinement.
Refinement tickets and coworking topics will be requested from the team every morning via the Slack workflow. When suggesting refinement tickets and coworking topics, we should also mention the audience, so we don’t need everyone on the call (e.g. BE, FE, PM or EM).
When suggesting a coworking topic, we should timebox the discussion. Anything over this timebox during the coworking should be paused and moved to a dedicated meeting or async. Discretion can be used here to continue the discussion on the coworking if there are no other topics; or, if the other topics are short, to pause and come back to the discussion after the other topics.
Sprints
We run two weekly sprints with an optional midpoint sprint review check in. Sprints start and end on Monday. The sprint will be closed on Monday morning, so the team should endeavor to complete their work by the end of the day on Friday. Sprint review demonstrations will take place on the Tuesday following the end of the sprint.
We only commit to the average of our delivered sprints. The exception to this is when an issue comes from the previous sprint or if work has begun on an issue. If the remaining work on an issue is less than the original issue size, we can calculate and commit the story points with the remaining estimate, rather than the full issue size. This will be calculated outside of Jira and we will not input “revised estimates”.
Here’s an example of how this might look in practice:
One issue worth 5 story points was incomplete from the previous sprint. The average sprint commit is 15 story points. The team estimates that 2 story points remain. In this sprint, we would commit to 18 story points, knowing that the actual work (i.e. the new sprint plus the remaining 2 story points) is equal to 15.
Issues will not be removed from a sprint until the sprint is complete, regardless if the team knows the issue will not be picked up. There is an exception to this: If you need to add something to the sprint, you may choose to remove something that is sized similarly, to avoid engineers committing to more than they should.
If there is no work left to be picked up at the end of the sprint, devs may choose to start work on issues that are the highest priority in the next sprint. These tickets will remain on the board for the upcoming sprint, but if an engineer is confident in completing them before the end of the current sprint, they can move them to the current sprint.
If an issue is incomplete at the end of the sprint, the size input into Jira on the ticket will not change and we will be “officially” committing to the same size in the next sprint, but as shown in the earlier example, we will have calculated the real value in our actual commit.
We will flag issues if they are blocked by some factor (e.g. dependency on another internal or external team, etc.) and we will add the reason for the flag to the comments of the ticket. If an issue is flagged and cannot be continued due to a blocker, we may consider splitting the issue if there is a natural break point and something can be delivered before the blocker. Anything relying on the blocker will go back into the backlog until the blocker is removed.
The blocked issue or the blocked issue after the split must be linked (i.e. blocked by) the Jira issue causing the block, be it on another team or on this team itself. If there is no ticket to link to, consider asking for it to be created or creating it yourself.
Code reviews
If the merge request (MR) review process is taking longer than desired, causing delays in delivering changes and slowing down our development workflow, we can address this by focusing on breaking down MRs, distributing the review workload and prioritizing critical changes.
To achieve this, team members should follow this list of principles and guidelines for reviewing:
Principles:
Regular code reviews: We encourage all team members to review code multiple times a day, ideally in the morning and evening. Regular code reviews foster collaboration and ensure thorough feedback.
Breaking down changes: We encourage MR owners to divide larger changes into smaller, focused MRs. Smaller MRs make it easier for reviewers to understand the changes and provide prompt feedback, improving the efficiency of the review process.
Prioritizing critical changes: Reviewers are encouraged to prioritize critical or time-sensitive changes. This entails identifying MRs that have a significant impact on the project, align with upcoming deadlines, or address crucial bugs or security vulnerabilities.
Team goals and collaboration: As a team, we share common goals and responsibilities. To ensure we focus on the most impactful work first, reviewers should prioritize completing code reviews over their own tasks if a specific MR ticket has higher priority than their own. This collaborative approach enables us to achieve our team objectives and deliver changes promptly.
Guidelines for reviewers:
Handling large MR reviews: If asked to review a large MR, inquire with the owner about the possibility of breaking it down into smaller MRs. If this is not feasible, suggest conducting a live code review session in a Zoom call with the MR owner.
Giving priority to MRs over tickets: At least twice a day, identify and prioritize high-impact, time-sensitive changes that take precedence over your own ticket. Focus on reviewing and addressing these prioritized MRs promptly to ensure timely delivery.
Managing context for MRs: We should aim to minimize lengthy or open-ended conversations on GitLab. If you require additional context regarding the approach taken in an MR, please continue the discussion on Slack. You can use private messages (PM) or the appropriate team Slack channel, depending on the audience. Leave a note in the MR conversation indicating that the discussion was continued elsewhere. If the discussion wasn’t completed in PM or Zoom, include a link to the ongoing conversation.
Addressing knowledge gaps: To ensure knowledge gaps are addressed quickly and often, reviewers must signal when they lack the necessary context to review with a comment on the MR, allowing authors to proactively bridge the context gap.
Conclusion
By adopting these well-defined Ways of Working, we have seen many benefits. Everyone on the team now has a say in how we work, which has dramatically improved the team culture. We are able to propose changes to the ways of working more frequently to test and try out new working methods, without the significant pushback that we would have previously encountered.
We have reduced friction for new joiners, smoothing out their onboarding process so that they can deliver impact quickly. This process also allows us to more readily cater for team splits or change in direction, as we can quickly review the template and add or remove the sections based on the direction of the new team.