Skip to main content

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. We occasionally build quick win features for large deals, but we are optimising overall value not just for specific clients.

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 on the Tech Debt Radar — our Product and Engineering Backlog board — and score it with RICE, so debt can be weighed against other product work rather than argued for on feel. We realign the radar quarterly (the internal Engineering System Audit template is a useful input here), and each team allocates a portion of its capacity per quarter to working down it in RICE order. Quick wins get picked up in the gaps between other work.

See How we track technical debt for what each entry should contain and how to score it.

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.

Summarise 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 Confluence docs
  • 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
  • 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 - always deployable. Don't merge code that's un-tested or requires a specific rollout process to work. It's 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 it's passed story QA on dev (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 it's ok to merge something in if it's part of an unreleased feature that's not visible to all. If visible to all it needs to pass QA before being merged.
  • Merging to main deploys to stag, where release QA happens before we promote to production. See Development Lifecycle for all three QA points.

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/task.
  • Merge PR into main AFTER story QA has passed on dev.
  • Write a meaningful summary of the change