How to Manage a Software Engineering Team During PMF Phase

By Luan Guimaraes, co-founder and CTO at deX Labs

blogpost image

By Luan Guimaraes, co-founder and CTO at deX Labs

Hi! This article describes our approach to dealing with product management in the early stages of a highly technical business like deX.

The ultimate goal is to (1) generate ideas that meet business needs and (2) lead the team to implement them quickly and with high quality.

So far, we’ve been successful in managing the technical team and building a functional interface between them and the product. Especially as young entrepreneurs, we understand that organizing all the tasks is hard, and that’s why we decided to share how we do it.

The seven guidelines of our process

First of all, we list the 7 fundamental principles of our process.

  1. Our team values agile, flexible, and asynchronous work.

  2. Our process is designed to increase the efficiency of asynchronous work.

  3. We set deadlines to help prioritize tasks, not to create chaos.

  4. We always plan and align before we execute.

  5. The board is our central hub; a disorganized board indicates a chaotic team and a poorly executed product.

  6. It’s everyone’s responsibility to provide visibility and organize their own work.

  7. We never start work without first describing a card for the task.

So, let’s get started.

Our tool of choice, GitHub Projects

We decided to use GitHub Projects as our main task management tool. I admit that it’s not the most popular tool, but in our case, we found all the functionality we needed AND it’s really close to the code. All of the following boards, tasks, and tags are built on top of GitHub Projects.

Not Scrum, nor anything similar

Although we use certain terms and practices from agile methodologies such as Scrum and XP, our process is unique and continuously adapts to our specific context.

We have developed our own way of working based on past professional experience and the organizational methods of open source communities in distributed environments.

In practice, we hold only one weekly meeting to address any roadblocks and determine the team’s next steps. Most planning is done asynchronously through issues, design documents, and comments. Occasionally, we have additional meetings to discuss specific issues that require immediate attention, but these are rare, and we prioritize minimizing unnecessary meetings.

Process Simplifications

Each process requires different levels of abstraction to effectively translate business needs into actionable tasks that deliver tangible solutions.

All stakeholders should be able to understand the solution domain and interact across these different levels of abstraction to ensure that business and development expectations are aligned.

At deX, we organize our work around the following abstractions:

Releases

Releases are the highest abstraction of a deliverable. They are sequential; ideally, we would only work on one at a time. It is the role of deX leadership, with the help of the entire team, to define the following business objectives and propose future releases based on them.

Releases typically have a leading theme (e.g. ingestion integration, ETL module integration) but can have additional work fronts. They are composed of epics and typically last about a quarter but can be shorter or longer depending on the complexity of the implementation.

The development of a release may involve several refinement cycles with design documents and brainstorming sessions. It is up to the deX leadership to involve the necessary stakeholders in the release design and segmentation of the release into one or more Epics.

📌 The release manager is the person responsible for bootstrapping the Release.

Our releases have a title and a versioned ID, for example, v0: Transformation Backend Release and v1: Ingestion Integration Release. We have a list of releases and their respective epics on a Github Projects dashboard.

Epic and Releases Dashboard

⚠️ It is mandatory for all other abstractions, from Epics to Tasks and Bug Reports, to identify the Release parameter to which they are linked.

Epics

Epics are the follow-on element within releases that represent a large, cohesive set of Features and Operations. They describe complete user experiences or significant changes that have a major impact on the platform.

Each Epic is associated with a single Release, and there is no predefined deadline for its completion due to the varying complexity of each Epic. Therefore, once the Features and Operations that comprise each Epic have been planned, it is the responsibility of the Release Manager to establish an estimated delivery timeframe for the Epic.

Unlike Releases which contain only a title and a version tag, we create each Epic by defining issues with the parameter Kind: Epic and the label kind/epic in the project.

Epics also have a unique ID (e.g., EP01, EP02) that grows sequentially.

⚠️ All Features, Operations, and other abstractions under an Epic must have the Epic parameter to which they are linked.

Epics, Features, and Operations

📌Each release contains a specific Epic called Meta. This Epic is used to define issues that are not related to the goals of the release itself, but rather to aggregate configuration tasks and monitoring of the release itself.

Features and Operations

Features, as the name implies, are standalone functionalities that can represent an experience, a resource, a flow, or any other deliverable that impacts the user experience. Features are entirely user-facing and should provide clear value from our customers’ perspective.

Each Feature belongs to only one Epic and must be referenced by an issue with the parameter Kind: Feature and the label kind/feature within the project.

We believe that a comprehensive description of a Feature is crucial. The description should include the design, acceptance criteria, and any other essential information to ensure a clear understanding of the work for all involved parties.

Initially, the person responsible for defining the Release configures and describes all the Epics and their respective Features to align them with the goals of the Release and organize them from a business perspective. However, it is unrealistic to expect a fully finalized description and design at this stage, as the release manager and leadership may not have all the technical insight required to conceive certain Features.

Therefore, it’s critical that those responsible for executing/implementing Features understand the context, clarify any points, and even enhance the documentation before breaking down the deliverable Tasks.

Features are not product area-specific. We do not create different features to describe a functionality that requires tasks from design, backend, and frontend to build. As the process progresses, each squad will have the opportunity to break down their own deliverable Tasks and coordinate their work with the other involved squads to efficiently deliver the entire Feature.

📌 The only issue that describes each Feature aggregates several sub-tasks from different areas.

Successful integration of different responsibilities requires a high degree of autonomy and proactivity. Team members must reach out to stakeholders and get the clarification they need to get their work done.

Features do not have IDs, so we do not have a specific parameter to associate tasks with their respective Features. Instead, we use a [suboptimal] feature of Github to keep track of which Tasks are under which Features. In the section on Managing Tasks below, you can see how we do this in practice.

Operations follow the same principles as Features but are used to define non-user-facing goals. These can be infrastructure features, environment configuration, development process improvements, performance optimizations, etc.

This distinction is critical to understanding the amount of time we spend implementing functionality that directly benefits customers versus the amount of time we spend optimizing and improving internal processes. It serves as a benchmark that allows us to improve our prioritization processes and consistently strive for maximum efficiency, balancing quality and speed in our deliveries.

Operations are defined by issues with the parameter Kind: Operation and the label kind/operation on the General project.

📌 You can see how we create Features and Operations in the section Managing Releases.

Tasks

Tasks represent deliverables at their most basic level. They are created by the team members responsible for developing Features and Operations and should have only one owner.

Each Task becomes a card in the Development Backlog or on the Development Board. We’ll talk about these boards in the section Managing Tasks below, but here’s a screenshot of our development board.

We do not have sprints or any other concept that limits the life of a Task itself. In fact, the owner can define Tasks as granularly as they like. Some like to see their work move through the boards with many small Tasks, while others prefer to describe an entire deliverable in just one card.

The main tip is to define Tasks of a reasonable size so as not to flood the board, which is a shared environment. As a general rule, think of a deliverable that can be completed through a Pull Request, not a commit. You wouldn’t split a Task into two cards, “make component X” and another “test component X”.

As with Features and Operations, we value a clear description of the work being developed in each Task. Therefore, it is important for the task owner to provide a thorough description of the body of the issue. This description allows others to evaluate the work, track its progress, and actively participate through comments.

From a management perspective, the Task is the most important element. It allows us to allocate resources to the right initiatives, prioritize critical work, leverage dependent solutions, and resolve conflicts between different areas. Therefore, the development board is our primary tool during the weekly team alignment meeting.

During this meeting, we review all completed, in-review, and in-progress tasks on the board and align the team for the upcoming week. It is important to note that this meeting does not represent the end or beginning of a Scrum Sprint; it simply serves as a checkpoint to ensure that the team continues to work efficiently and without roadblocks.

Bug Reports, Technical Debts, and Trackers

Bug Reports and Technical Debts are specialized task types that define deliverables. These items should have a single responsible party and, like Tasks, should have a clear description of the work that needs to be done.

Bug Reports should be issues with the parameter Kind: Bug Report and the label bug. Technical Debts should use the parameter Kind: Technical Debt. Both should be associated with the current release when they are created.

There are two particular issues called “Release Bug Tracker” and “Release Technical Debt Tracker” under the Epic Meta of each release. These issues are of the type Kind: Tracker and are intended solely to aggregate the effort expended on resolving technical debts and bugs within the context of a release.

Other Types of Issues

Partial Task: These are usually subtasks that need to be reviewed during the development cycle of the primary Task. This card is often a PR with partial changes and must contain the reference to the primary Task to which it is associated. Like the Task, it should have a detailed description of the work being done.

Feature Request: This is our primary mechanism for gathering ideas and needs that will shape future Releases. Feature Requests start as ideas and suggestions, but should be refined through comments on GitHub until they are ready to become features and operations in future releases. The person who created the issue is responsible for tracking the progress of the work being developed.

📎 The team can suggest new ideas through Feature Requests on a specific board

Security Issue: These are highly critical issues that require immediate attention. They refer to security issues that could put deX users and internal information at risk.

Experiment: An issue that is not tied to a release and is used for experimentation, whether with new tools, libraries, or even evaluating competing platforms.

Project Tree Overview

When you put it all together, this is what we have.

Project Tree Overview

Managing Releases

Release management begins with the collaborative definition of what will be delivered in the Release. This is done by the deX leadership and team, who evaluate business objectives, high-value deliverables, and the feature request list.

Once the implementation plan is complete, the release manager is responsible for designing the key architectures and understanding the key requirements of the components to be developed.
After validation, the work is broken down into large Epics, Features, and Operations.

The Release Manager’s job is to transfer all these discussions, documents, and descriptions to Github on a new page in the Epics Dashboard.
When Features and Operations are ready for development, the Release Manager notifies the team. Each person assigned to work on the features is responsible for understanding the context and defining the deliverable tasks.

Managing Tasks

Here’s a decision tree to help developers decide what to do next.

Taks Management Flowchart

Understanding the Problem

If you are assigned to develop a Feature, your first step should be to visit Epic’s Dashboard and thoroughly read the description of the Feature or Operation.

Since the release manager may not have provided all the details regarding the development of the functionality, it is everyone’s responsibility to consider the full context of the feature. If necessary, improve the descriptions, define and refine acceptance criteria, and involve other stakeholders to resolve any outstanding issues.

📎 For more complex features, or when it is difficult to visualize potential solutions, it is advisable to create a design document to evaluate the work to be developed in advance.

Creating Tasks

Once you fully understand the context of the feature you are developing, it is time to create tasks.

🚨 We always start by defining a Task on the Board, which includes a description of the work.

Steps for Creating Tasks

  1. Go to the Tasks Board.

  2. Create a new card by clicking on ‘+ Add item’.

  3. Define the title of the task clearly and directly.

  4. Provide a detailed description.

  5. Link the card to the corresponding feature or operation.

  6. Add a label that indicates the task’s type, such as Task, Security Issue, Bug Report, etc.

  7. Assign the task to yourself.

Tracking Tasks Through Their Lifecycle

Task lifecycle management involves two different boards: Development Backlog and Development Board. Although these two views are separate, they are a continuation of the same workflow.

Task Lifecycle

Our Development Backlog board ends in Promoted, and the Development Board begins there. The end of one board corresponds to the starting column of the other board, ensuring a continuous flow of tasks from our backlog until they are ready for development.

As mentioned in our Task creation example, we start with the task at the ‘Promoted’ stage. However, it is perfectly acceptable to place a task in the backlog instead of the development board. This is often the case with Technical Debt and less critical Bugs.

It is important that everyone feels responsible for managing the issues queue properly, and that starts with understanding how issues should be moved through the development cycle.

Understanding the Columns in the Development Cycle

Sketch: This column contains general ideas that are not well developed and need to be discussed and adjusted before entering the development workflow. Many cards in this column are just sketches and are not part of a release.

Semester: This column represents our most distant deadline. We avoid expending effort on tasks that are not within a six-month horizon; that is, if you are looking at a task that is a year away, it should not be your current concern. Often tasks in this column are not well documented and may not be part of releases or features. That’s okay — tasks here will be refined in later columns until they are ready for development.

Quarter: Technical debt, bugs, and even tasks that are meant to be done only at the end of a release are typically placed here. We have a ~3-month horizon to address these items. The team manager ensures that tasks on this board actually get done, but the creator of the task is responsible for monitoring its progress through the cycle.

Prioritize: Issues should be prioritized as soon as possible and need a better description. The creator of the task should refine the requirements and acceptance criteria, and provide any additional information to ensure full assignment and execution of the task.

Development Backlog

Although well described, these issues may not yet be part of a release and may not have an owner.

The Team Leader often visits this board to assign new tasks and promote those that are ready for development.

Promoted: At this stage, a Task should have a thorough description, an owner, and all of the required parameters: Release, Kind, Domain, Priority, Epic, Progress. If you have a card in this column, it is important to move it to ‘Scheduled’ as quickly as possible.

Scheduled: Once a card enters this stage, the owner party must define an estimated timeline for completion of the task, setting the parameters Task start and Task end.

They must be accountable for proper time management. This deadline is important for the manager to provide the rest of the company with a picture and estimates of when tasks will be completed.

Tasks in this column are ready to be developed as soon as the owner is able to do so.

In Progress: Cards here are actively being developed. If this is a development task, a pull request needs to be associated with this issue. The easiest way to do this is to create a draft PR and in the PR description add Closes #<issue-id>, which will automatically link the PR to the issue.

We interact a lot through these cards, so use Github’s issue comments to raise any questions and tag necessary people.

Review: When a task is completed, it doesn’t go straight to ‘Done’. Our process relies heavily on a culture of peer review, which means someone has to review your work before it’s considered done.

For an issue with a linked PR, you’ll need to set your PR to Ready for Review and assign a team member to review it. In the meantime, don’t forget to move the card from ‘In Progress’ to ‘Review’—Github doesn’t do this automatically.

Now, wait for your colleague to review your work and request changes if necessary. Keep an eye on Github notifications.

Need Changes: If the reviewer requests changes, you need to address them before moving forward. Move the card to this column and work on the feedback provided. Once the required changes are made and the reviewer approves, you can move the card to ‘Done’.

Done: This is the final stage of the card’s journey. Your task is now complete, and the result is integrated into our workflow. Be sure to close the issue and associated PR (if applicable).

Conclusion

Remember that all team members are responsible for managing the flow of cards on the board. It is a collective effort to maintain an organized and efficient workflow. If you are unsure of where a card should go, ask a teammate or team leader for guidance.

Build something great.

dex logo

deX is a cloud platform for big data analytics and data science, enabling innovative teams to collect, transform, and orchestrate data pipelines efficiently.