How I lead a technical team
Until May 2026 I led the TAPI team within Assessment & Research Capabilities (ARC) at Cambridge University Press & Assessment - the group behind the Text and Speech APIs that power AI auto-marking across Cambridge English assessments. This page is what that work taught me about leading a technical team. I am a hands-on technical leader, not writing a conventional line-management manifesto. Most of the job is getting a small group of people to own real problems and do their best work; the docs, decisions and metrics further down exist to keep that ownership visible, not to run people from behind a wall.
context
We built and operated two production systems - a Text API and a Speech API - across five environments, feeding products such as Write & Improve and Speak & Improve. The primary mission was not a roadmap slogan: it was to meet the SLAs and keep the APIs available. The service record available to the team reported 99.98% uptime for both APIs over the 12 months to April 2025. Everything below is how we organised around that reliability responsibility.
the kind of team
I am at my best in a hands-on technical role with about four to six other engineers - a mix of junior, mid and senior - working remotely. I have run that shape more than once: at Cambridge, and earlier as a Staff Engineer at OneStudyTeam (part of Reify Health). Same pattern both times - still writing code, still owning hard problems, and still responsible for how the team delivers. At Cambridge we still met in person several times a year; those gatherings mattered for trust and shared context that are harder to build on a call alone. The daily standup pulled some of that weight day to day: on a remote team it is often the only time people talk to each other all day, so it is as much about staying connected as clearing blockers.
people and motivation
A team is not a resourcing spreadsheet. The first job is to understand the people on it as individuals: what they are good at, what they actually want to be doing, and why they are here at all. People are motivated by very different things. One person wants to go deep on a hard problem. Someone else cares most about shipping things real users touch. Another just wants a whole area to themselves and the trust to run it. If I assume everyone is wired like me I get it wrong, so I ask, and I use 1:1s to listen rather than to collect status.
What I am really trying to build is ownership, and that does not come from assigning tasks. It comes from someone understanding why a piece of work matters and owning the whole of it, decisions included, not just the tickets. On the Cambridge team that took the shape of epic champions. The docs, RFCs and boards further down are there to keep that ownership visible, to the team and the wider business alike, not to stand in for trusting people to do the job.
Growing the less experienced engineers is part of the same job. That means ownership they can actually finish, lower-risk changes treated as a chance to learn rather than tickets to rush through, pairing, and code review that stays about the code and not the person.
When someone is struggling, or a commitment starts to slip, I would rather deal with it early and in private than let it drift or turn it into a verdict. The honest question is usually what is actually getting in the way: unclear work, missing context, the wrong task, or something going on outside work entirely. More often than not the answer is pairing or re-scoping, not pressure. You cannot get someone's best work by denting their confidence first.
the wider business
The API team sat in the middle of three: a product group owned what clients needed, a research and ML group (Applied AI) owned the marking models, and we built and ran the APIs between them. Protecting a team in that setup does not mean walling it off. The opposite worked better. Anything that spanned teams had a single named owner so it did not fall through the cracks between us, and we kept what we were doing, what we had decided, and why, visible to everyone around us. The roadmap was deliberately outward-facing: flexible, usually wrong about exact dates, but an honest picture of what was coming, so stakeholders could argue with reality instead of a rumour.
Going to bat for the team was usually unglamorous. It meant guarding their focus, since engineers need uninterrupted stretches to do good work, and being straight about tradeoffs when priorities collided: here is what this costs, here is what it delays. Stakeholders shaped the work through that conversation, not by pulling rank, and when something genuinely exceeded what we owned it got escalated rather than absorbed in silence. It ran the other way too: a good part of the job was making the research team's models easier to ship, which is what the hand-off further down is about.
one front door
Team knowledge lived in one shared documentation space. The first thing on the home page was the incident response process - what to do when something is on fire - then everything else. Nobody was expected to read hundreds of pages cover to cover. The point was that any question had one obvious place to look: how we deploy, why a queue is shaped the way it is, or what we decided about versioning and why.
- Architecturesystem design and service docs
- Practiceshow we engineer - CI, testing, IaC, review
- Processesceremonies, on-call, incident response
- RFCsdecisions with a clear lifecycle
- Guidesstep-by-step operational how-tos
- Reportsservice versions per environment, daily/weekly costs, assessor diagnostics, acceptance tests - mostly auto-published
- Incidentspost-incident reviews
- Glossary & onboardingshared language and a path in for new joiners
If something changed, the docs changed with it. Stale documentation is worse than none - it misleads. A lot of the operational picture refreshed itself: which version of each service was in each environment, what we were spending, how assessors were performing, and whether acceptance tests were green - published on a schedule so nobody had to remember to update a page. The same front door is what made onboarding work - a new joiner could find how we deploy, how we handle incidents, and what the systems look like without waiting for someone to explain it from memory.
decisions and ownership
Technical decisions went through RFCs: a short document that states the problem, explores the options, and proposes a solution, shared early rather than when it was perfect. Each one carried a status - draft, open for discussion, accepted or rejected, implemented - so anyone could tell a live proposal from a settled decision, and the author recorded what was decided and by whom. Context survives the meeting.
Disagreement is normal, and I would rather have it in the open than smoothed over. When two people genuinely differ on a technical call, I try to move it off opinion and onto evidence: a quick spike, a prototype, or an RFC that lays the options and tradeoffs side by side. Most arguments dissolve once everyone is looking at the same thing. When one does not, someone is named to make the call, we write down why, and we move on rather than let it fester.
Day to day I still spent most of my time coding - early prototypes, the trickiest problems, figuring something out before it went to the team. Alongside that I tried to make myself almost unnecessary as a bottleneck: people picked up what they were good at and took responsibility for it, while I kept the documentation neat, gave advice when asked, and cleared the path. Most people want to do good work; give them clear ownership and they usually will.
That is why no epic was in progress without a champion - one person responsible for organising the tasks, keeping the epic documented, being the point of contact for questions, and driving it to done. Team members picked up epics themselves; I championed a few, but deliberately fewer than most, because the job was to spread ownership, not hoard the interesting work. It still took light curation to keep delivery pointed at what the organisation needed - but ownership never evaporated into "the team".
diagrams as shared truth
I am known for insisting on good diagrams. Not decoration - a picture most people on the team can read in a minute, then use as the common reference in a meeting. When everyone is looking at the same boxes and arrows, arguments get shorter and decisions stick.
Where it is practical, diagrams are generated from code or other sources of truth and kept under version control - Graphviz, Mermaid, and similar - so the picture cannot quietly drift from the system. CI can render them and fail the build when they are missing or stale. Public examples of that habit are in my own repos - for example galacto and evo.
Sometimes the right tool is still Miro. Remote workshops need a board people can grab and rearrange together; a hand-drawn sketch in the room beats a perfect diagram that nobody edits. The ones worth keeping get formalised later. The ones that only need to unblock a conversation can stay on the board.
practices
Engineering habits were written down as practices - short pages that said what we believed and how we applied it.
- Agiletwo-week sprints, daily sync, planning and retro - take what works, drop the rest
- CIevery push builds and tests via GitHub Actions; red means do not merge
- CDcode that passes CI can ship; promote through environments with tests at each stage - see continuous delivery
- Deploy ≠ releaseget code into production without forcing users onto it - feature flags, assessor versioning, API versioning
- Automated testingunit, integration, and acceptance tests; acceptance results published per environment
- Code reviewAI pre-review, then a human - small PRs, separate refactors from behaviour changes
- IaCinfrastructure in Terraform, reviewed by PR - no manual console changes as the normal path
- ObservabilityCloudWatch and Sentry in production; consolidating toward a single pane of glass
- Securitysecrets managed properly, least-privilege access, private networks, and hardening treated as ongoing work - not a one-off audit
- Documentationa shared team space for how we work; READMEs in repos; if it changes, update the docs
processes
Practices say what we believe. Processes say how the week actually ran - from backlog to production, and from alert to post-incident write-up.
- Backlog → doneepics with champions → sprint planning → small PRs → review → deploy → acceptance green → close
- Daily syncshort weekday standup - progress, blockers, coordination; long debates moved to the end
- 1:1sabout every two weeks with each person - are they okay, any blockers, are they doing work they want to do
- Planningfortnightly; champions prepare their epics ahead of sprint planning
- Retrofortnightly; actions become tickets, not wishes
- Stakeholdersregular meetings to prioritise and discuss upcoming work
- RoadmapJira Timeline - always in flux, but a clear outward picture of what we were doing and what was coming
- On-callweekend and bank-holiday cover for the APIs, a written escalation path, and alerts that phone a person rather than ping a channel
- Incidentsdetect → classify fix-now vs schedule → recover → write it down; process lived on the docs home page
The 1:1s were light-touch on purpose. Mostly checking people were fine and unblocked, encouraging training and 10% projects, and occasionally hinting at work that might suit them - without pushing anyone into a particular path.
ops that stay boring
Operations should be dull. The exciting version is called an incident. Detection came from monitoring and from people; triage decided whether to fix now or schedule; recovery followed a written process; then we wrote down what happened. Nobody was expected to debug from memory at three in the morning.
We cared about DORA-style delivery metrics (I started github-org-metrics to pull numbers from GitHub, but it never became a solid DORA tracker - a rough steer at best). A manually gathered snapshot estimated change failure rate at around 1% while we shipped several times a week per service; the methodology still had gaps, so we treated it as indicative rather than exact. Those numbers were a read on the system, never a scoreboard for individuals. When one moved the wrong way the useful question was what is making good work harder, not who to blame; the moment a delivery metric becomes a stick, people optimise the metric and you learn nothing real.
handoffs across teams
Our Text and Speech APIs both depended on models and scoring services built by Cambridge's research and machine learning group (Applied AI). While I was leading the API team, the handoff I pushed was practical and service-shaped: get those colleagues onto our AWS accounts, give them a Sandbox that behaves like production, and make each scoring service a well-behaved container rather than a research artefact thrown over the fence. That pattern was furthest along for Text Assessors; Speech was still more primitive when I left, and we were starting to put a similar path in place there.
- AWS accessguides so research colleagues could sign in, set up keys and MFA, and switch accounts without tribal knowledge
- Sandbox parityrun the same service path on ECS as production; change an image tag in Terraform, apply, then prove it with Sandbox e2e tests
- Service standardscurrent Python and deps, a clear assessor interface, redacted logging, localstack e2e tests, and CI that lints, tests, versions, and pushes images to ECR
- Branch buildsmanual workflows to push a branch image to ECR so a change could be tried in Sandbox before merge
- Deploy ≠ releaseSandbox via Terraform; other environments via ticket; patches vs new parallel versions so clients were not forced onto breaking behaviour
The point was a shared path from "it works on my laptop" to "it is running the same way it will in production" - with tests and versioning as the contract, not a meeting.
ai in the workflow
On the Cambridge team we used AI where it saved time without replacing judgement: Copilot pre-review on pull requests before a human review, and tooling that turned noisy error streams into clearer tickets and a tidier backlog. The tests, docs, and ownership model above are what kept that assistance honest. The rule was simple: you are accountable for every line, whether you wrote it or an AI did, and you do not ship code you cannot explain.
Breaking a problem into pieces, giving clear ownership, and checking the result is the same skill whether the teammate is a person or an AI agent. Years of leading a mixed-seniority remote team turn out to be excellent preparation for working with agents.
More about the work
Skills, history and live projects are on the CV - or get in touch.
last updated: 2026-07