How We Work


We on the engineering team have put a lot of thought into how to best work together to ensure we iterate quickly with quality, while not burning out. We’ve formulated this working agreement that I’d love to share and get any suggestions or feedback on. We’re always thinking about how we can do better!
v1.3
Overview
To build a well-designed, efficiently functioning engineering team, we should agree on how we work with each other. These principles will guide us in day to day decision making and ensure we know what to expect from each other. This is a living document and will evolve as the team evolves and with everybody's input.
Workflow
Standup / Daily Sync
Asynchronous Written Standup
You should post daily whenever you start work in the Slack #standup channel a detailed status update that includes:
What you accomplished previously / yesterday
What you plan on accomplishing today / next
- Indicate your top focus by putting a
(TF)
next to the item that's most important today
- Indicate your top focus by putting a
Any blockers, dependencies, or obstacles in your way
Call out any team members you're depending on
Help team resolve blockers asap!
Synchronous Video Standup
For our synchronous video standup, you should focus on just 2 things:
1. The most important thing you want to accomplish today (TF)
2. Any obstacles in your way to accomplish that thing
If anybody has any blockers, the team should rally to remove those blockers and get everybody productive asap.
Sprintly Recurring Events & Ceremonies
First Monday
- Sprint kick off / planning meeting - 1h
Finalize previous sprint and review tasks to be delivered in current sprint. Ensure estimates are accurate and tasks are well-defined. Commit to delivery.
- Push to Production - 1h
As long as no critical or high priority bugs exist. If P0 or P1 bugs exists, need to fix asap before we can release to production.
First Friday
- Mid-Sprint Checkin - 30m
Check-in during standup to see if we're on track for the week to deliver all our commitments for the most important epics on the roadmap. If it looks like anything will slip, see if we can potentially shuffle around any work.
2nd Thursday
- Demo Prep
Take some time to prepare for your demo so that you can successfully show off what you've accomplished in the sprint.
- Demo
Demo the most impactful things you've accomplished in the sprint. Limit it to 5m and really highlight the most impactful things. You don't need to demo every single thing you did, especially not bug fixes (unless they're very impactful).
- EOD code freeze
Wrap up an PRs you're working, help other devs get their code merged in, and start testing and preparing your demo.
2nd Friday
- Internal Testing
We should focus on testing the changes, fixes, and updates we just implemented in the last sprint. We should ensure the team is equally split between testing mobile, desktop, and BE. We should test on staging builds.
- Next Sprint Proposal and Estimation
Karim will work with Drew on the roadmap and propose tasks for next sprint and team should give their own estimates. All tasks should be reviewed and estimates completed before the sprint kickoff session on Monday.
Planning
In order to work effectively, we must ensure that the work we plan to do in any given sprint is clearly-defined and actionable. That means that before we commit to doing some work in a sprint, that we've fully digested the task and asked any clarifying questions if we need to do. It also means that we've called out any dependencies and worked with product or engineering leadership to ensure those dependencies are prioritized and actionable by the right person or group.
We should NOT commit to doing work in a sprint if it's not actionable
(Unless it's an emergency and/or it's super important that the work is delivered in this sprint. If we have dependencies in a sprint that need research to properly estimate, we can adjust sprint commitments after necessary research is done.)
Tech-Specs
Any non-trivial piece of technical work, and especially for any new APIs, or updates to APIs, we should write a tech spec to align on how we're going to do the work.
This will ensure everybody is happy, or at least on board, with the implementation details and will help to reduce technical debt going forward. As with everything we do as a startup, there needs to be a balance between doing things the safest / most optimal / most scalable / most correct way vs moving fast. We can talk about those trade-offs in the tech spec and associated meetings (if necessary).
Individual Task Workflow
- Move your highest priority task from 'TO DO' to 'IN PROGRESS'
Humans are by nature single threaded - You can only do one thing at once, so ensure you only have one task IN PROGRESS at any given time_. Anybody in the company should be able to look at our sprint board and know exactly what any of us are working on this very instant._
For any coding task, no matter how small, create a branch for your work using the ClickUp UI.
We should shoot for smaller, more focused PRs.
PRs should accomplish a single thing. Smaller PRs are easier to digest, test, and review than large PRs. This ensures quality and alignment. Totally fine to have multiple PRs per ticket - not totally fine to have multiple tickets per PR.
- Commit early and often.
Commits should be for small subtasks and the message should be a short description of what you did._
- When a coding task is done, create a PR
ClickUp should automatically move the task to REVIEW_. When the PR is merged, ClickUp should automatically move the task to_ STAGING_._
Explicitly request review from at least one contributor to the repo so they get a notification about it
If changes are requested, as soon as you make changes and are ready for another review, click the button in Github to re-request review so the reviewer is notified.
Communication
Since we are a globally distributed team, we should default to asynchronous, written communication via Slack. If there are more than a few back and forths in Slack, then it's a sign that you should handle the conversation synchronously - either by huddling immediately or scheduling a future meeting if necessary. If you need to schedule a meeting, just fine time on people's calendar this is free. We should expect that people's calendars are up to date and reflect their availability.
In addition, since you can't always count on a quick response and back and forth with someone on Slack, we must ensure our communication is concise, but complete. Your written communication should leave no ambiguity to the reader. You should always err on the side of over-communication if you're ever unsure.
Cave / Focus Time
Engineering work requires deep focus. You can and should plan to eliminate distractions from your personal life and your work life so that you can do your best work.
You can add focus time to your calendar to ensure you aren't disrupted by meetings. You can also set your Slack status to 'Cave Time' to indicate to coworkers that they shouldn't disturb you unless it's an emergency.
Collaboration
We value collaboration and mentorship, and recognize that it's not a one way street. Of course, more junior people can learn from more senior people, but more senior people can also learn from junior people.
Availability
In order to effectively collaborate, we must be available to each other for synchronous work. Regardless of your timezone, you should be available for meetings, pair programming, and other synchronous things from at least the hours of:
0700 to 1000 PT
1000 to 1300 ET
1200 - 1700 UTC
1400 - 1900 CEST
Solving Issues
If you're ever stuck on an issue for more than 30 minutes, that's a good sign that you should reach out to the team for help. Likely, there's someone on the team who has seen your issue before and can save the team a lot of time.
Pair Programming
We value the practice of pair programming and aim to do it at least once per week with another developer on the team. We recommend the driver / navigator methodology. In this method, the driver is the one who is controlling the keyboard and mouse and the navigator is the one who tells the driver what to do, like you're driving a rally car together. If the driver disagrees, then the driver and the navigator should discuss the best implementation. This method is advantageous because it ensures the one who is not typing stays engaged and forces two way learning.
For most of us engineers, our natural inclination is to hunker down and solve problems by ourself. Solving problems together can be rewarding and fun! Make an effort to reach out to your coworkers and suggest a pair programming session!
Branching
For every piece of work we do, we branch. For consistency and for the tight integration with Github, we use the branch name provided by ClickUp:
Tip: branch names are not editable, but you can temporarily change the ticket name to something more git-readable and lowercase before creating the branch
Using the branch name from ClickUp will ensure that:
ClickUp automatically moves your task from TODO to IN PROGRESS when you push the branch.
ClickUp automatically moves your task from IN PROGRESS to IN REVIEW when you create a PR. ClickUp automatically moves your task from IN REVIEW to IN STAGING when the PR is merged.
Github will link to the ClickUp task in the PR.
Reviewing Code
Reviewing code earnestly is the single most important thing we can do to ensure the quality of our products, the maintainability of our technology, and knowledge share among the team.
Process
PRs should be created for every change, no matter how small. This enforces discipline on us and prevents us from going down a slippery slope of not getting things reviewed, not catching bugs, letting them get into production, and building a low-quality product.
When reviewing a PR, you should first verify it works as expected. On web, this means running the code locally or via a preview build. On BE, this means running it locally and/or simply verifying the functionality is covered adequately with unit tests.
Naming PRs
If you created a branch using ClickUp as above, the PR title will automatically be named:
CU-{{id}}/{{title}}/{{owner}}
Including the ClickUp ID in the PR title creates an audit trail so we can easily refer to the original issue.
What to Look For?
Clear purpose / intent:
Unclear code: many reasons why something could be unclear; anonymous complex regexp, poor naming, mega-functions, lack of commenting, etc. Think as much as you can about the next dev or even future you! Code is read 10x more than it's written.
Unnecessary code: for example, over-abstraction to the point of getting in the way, code broken out into a function for no reason, etc; TypeScript provides a slew of functionality (utility types, generics, type literals, etc) to prevent things getting complex
Appropriateness: does the fix make sense in the context of the wider code / service / api / module / feature? Sometimes diving into a small fix can miss the wider context (this should also be addressed at the planning stage)
Code that misses the point: is this a problem that even needs to be solved? Less code is better than more code, no code better than less code; review the big picture as well as the small picture to make sure we're not writing code that could remain unwritten
Reasonable code reuse:
Repeated code: does it make sense to abstract it away to enable cleaner and more maintainable code?
Before adding a new dependency, check if similar library already being used
Before creating utility function, search if there are relevant functions already created
Consistency:
Ensure file and directory naming is consistent with repo
Ensure component and classnames are consistent with repo
Ensure folder structure is consistent with repo
One class or component per file for easiest searchability
Clearly / consistently-named variables (where possible!) especially across related functions
Housekeeping:
Logical / functional errors
Commented code: we can always go back to old code; no need to clutter code base with commented code
Minor cleanups: if something can be cleaned up without affecting the functionality (i.e. risking a new bug); just do it
Support:
Automated tests: should cover at least the happy path and the most common error paths.
Documentation: were the functions commented helpfully, would they benefit from doc comments, does the feature require additional markdown documentation?
If making suggestion or criticism, try to add example or short code snippet on better way to do things.
Some Specific Things to Look For
For list of items `
` , use `key` attribute for each one
Use named exports always to remove ambiguity when importing
Poor typing or `@ts-ignore`; the compiler is your friend; understand any errors and mitigate
Missing types / generics: many functions can be typed using generics; missing this is akin to typing as `any` so you lose type safety
Who Should Merge?
A PR should signal an intent that you want to merge your code. As the author, if the code is not ready to merge, you should add a label like DON'T MERGE or WIP or leave it as a draft PR. If a reviewer approves of your PR, all CI checks pass, it has been tested, and the reviewer hasn't made any comments / suggestions then the reviewer should just merge it in.
If the reviewer approves, but leaves some small comments/suggestions, the reviewer should leave it to the author to either merge on their own or address the comments first.
Reviewers can also turn on 'auto merge' to merge a PR as soon as all build checks (tests, linting, approvals, conflicts) are resolved.
Review PRs in a Timely Fashion
If everyone on the team reviews PRs at least when they start work for the day and when they finish work for the day, we will ensure that no PR languishes in a non-reviewed state for more than 12 hours or so.
The faster we can review each other's code the better as we want to avoid developer context switching as much as possible. Also, the faster we review each other's code, the less likely it is that there will be conflicts to fix, which can be a source of frustration and bugs. Of course, if you are in deep focus, you should not drop that focus to review code unless it's an emergency.
Conclusion
This is a living document. Feel free to comment or make suggestions. Looking forward to building an awesome engineering team and an awesome product with you!
Subscribe to my newsletter
Read articles from Karim Varela directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
