How we work
Below we specify some default conventions we use. However these are tools to make us faster, if they make us slower its ok to go outside the box and work in a different way, however in that case please communicate the whys!
Attitude & Approach
Commercial First
We code to move business metrics, not for theoretical perfection. Engineering decisions should always trace back to customer and commercial value. If you’re deciding between “clean” and “impactful,” choose impactful and sustainable. Our north star: ship improvements that unlock growth, insight, or scale.
Small Slices & MVPs
Deliver value early, validate fast, and iterate often. GoodFit’s systems are designed for incremental deployment: every PR should be a small, testable, vertical slice. Avoid “big-bang” releases — instead, progressively enable features behind flags or environment gates.
Feature Requests
All features should align with product objectives and user research. Before writing code:
Validate the problem.
Define the MVP path. Confirm ownership and success metric. Engineers are encouraged to challenge unclear requests — collaboration beats compliance.
Guided by Product
Product defines what and why; engineering defines how. If requirements are unclear, start with a draft architecture note or prototype in a shared doc before building.
Technical Debt
We view tech debt as a managed asset, not a failure. Record debt in backlog tickets tagged tech-debt. Audit quarterly using the internal Engineering Health Review template. Allocate “maintenance Fridays” or sprint-end hours to cleanup.
Communication & Collaboration
Remote-First, Async-First
We’re a remote team — documentation is our meeting room. Prefer written and discoverable communication (issues, PRs, Slab) over ephemeral chat.
Summarize outcomes in Slack, Jira, Slab / docs.
Avoid private DMs for decisions — public threads scale context.
Use comments and PR discussions to teach through code.
Pairing & Calls
Async-first doesn’t mean async-only. If a Slack thread exceeds three back-and-forths - hop on a 15-min call. Pair to debug or architect complex flows, then document the result in the relevant issue or repo note.
Documentation
- Transient docs (ones that will be thrown away) - use Google docs and archive after
- Team / process or global cross cutting decisions - tech-docs repo
- System / code documentation - README.md in the relevant service or module - keep docs close to the code and update in the same PR.
How we plan and structure work
Stories (User stories / Tech stories)
- A story is a larger collection of tasks, often a sub feature of a larger product feature.
- There are 2 type of stories, user stories from the point of view of the user and tech stories for non user visible stories
- User stories are always user facing and typically start with "as a user". Never write internal as stories. 'As an engineer'. These are just tech stories. If it helps you can word tech stories as "The system can…".
- Good examples of user stories:
- As a user I can view and search a list of items
- As a user I can create a new item
- As a user I can edit an existing item
- Good examples of tech stories:
- The system can process an adhoc batch of page elements (this could also be a user story, or along side a user story, it does not matter too much)
- Page elements are loaded from the database not static config files
- Stories have Acceptance Criteria (ACs)s and are QAed against these ACs. This is called 'story level QA'.
- An AC is just a sentence like:
- When user clicks save the new item appears in the database with Id x.
- Item is validates and errors in fields X,Y,Z are shown to the user in the UI
- Typically QAed on test using code deployed from a feature branch
- We only want to merge to main AFTER story level QA has passed
- An AC is just a sentence like:
- QA can be by the engineer who wrote it, or, for more taxing items, another engineer in the team
- We trust people to ask for QA if they need it and skip it if its trivial.
Epics
- Collections of stories (both technical and user stories) that add up to some releasable feature.
- Eg a project or a phase of a project. Typically some milestone.
- Typically results in a 'releasable' thing (e.g. not a deployment, but something that has some release management around it see later)
- Epics also have their own QA plan in addition to individual story QA
- Epic QA should only happen after all stories within have passed story QA
- Typically epic QA will occur after code is deployed to prod and on prod (default but can be changed)
- QA is normally done by PM / lead engineer
How we do work
Branches
- See also Git conventions
- main - main branch always deployable to main. Don't merge code that's un-tested or requires a specific rollout process to work. Its expected that we should be able to deploy main to production at any point without fear.
- Story code should only be merged to main once its passed story QA (e.g. has been deployed to dev and QAed by yourself or another engineer) if it is user visible or could impact production systems
- May need eg feature flags to hide unreleased features - eg its ok to merge something in if its in an unreleased feature thats not visible to all. If visible to all needs to pass QA before being merged.
PRs
- Keep PRs small enough to review in < 10 mins.
- PRs are NOT a replacement for QA. Typically all that is in scope is "are there any obvious code issues" not "does this work". QA is more valuable than PRs typically.
- No more than 1 days of work in one PR ideally.
- Keep PRs allocated to one story ideally. Sometimes a tech story can impact several which is fine, however don't pull in multiple unrelated user stories into one PR.
- Merge PR into main AFTER story level QA
- Write a meaningful summary of the change
- We trust people to get PRs when they feel they need them. For a trivial or emergency change, feel free to bypass review rules. We might change this in the future, but whilst we are small.