How I work

What my day-to-day would look like on your team.

A CV says what someone shipped. It doesn't say how. This page answers that.

Getting into code I don't know

I start by walking through it, not by reading it.

In the first days on an unfamiliar codebase, I don't read at random. I pick a feature I can run and follow it end to end: the route, the controller, the model, the query, the render. One complete pass teaches more than ten files skimmed.

Then I look for where the code hurts, by reading the history rather than the code. The most-changed files are the ones the team dreads: those are the ones to understand first, and the ones to move through slowly.

My first contribution is deliberately small. Not out of caution, but because a small pull request validates everything else: that I understood the conventions, that I can run the tests, that deployment goes through. Only then do I take on larger work.

And I don't rewrite what I don't yet understand. An odd line often has a reason that is no longer in the code but in someone's head. I ask before deleting.

Working with agents

I treat them as untrusted code: closed scope, verified output.

I use assistant tools daily, and I've built some. The most complete is a read-only monitoring agent: it cross-references technical discussions with a skills map derived from my own git history, finds the answer in the source, and produces a sourced draft I approve or reject.

What interests me in these tools isn't the speed gain, it's how you contain them. On that agent: an allowlist of twelve read tools against a denylist of fifteen write tools, enforced at process launch - it physically cannot send a message or write a file. An anti-injection section in the prompt. A mandatory adversarial pass before every output.

On another tool, a review-material generator, the rule is that no code block ships unless it comes from the real diff, and a validator blocks rendering until it passes.

The principle is the same as for a third-party dependency: you don't trust it, you contain it. That's what lets you move fast without bringing code nobody has read into the repository.

My pull requests

Short, single-purpose, and the description says why.

I ship small and often: my pull requests are two to five files at the median. A PR that touches three subjects doesn't get reviewed, it gets approved out of fatigue. I'd rather open three.

I break a large piece of work into readable steps: the helper, then the interface, then wiring the data, then the tests.

The description says what changes and why, not what the diff already shows. If there's a debatable decision, I write it in the PR rather than waiting for someone to find it.

From a review, I want the decisions discussed, not the syntax: formatting is a tool's job, not a reviewer's.

And I review roughly twice as many pull requests as I open. That's where you learn a codebase, and where you're useful to a team.

Tests

I test what breaks: business logic and risky areas.

I systematically test pure logic and risky areas: my helpers, hooks and transformations ship with their test file alongside. On the back end, I cover controllers, jobs and exporters.

I put the effort where it pays: edge cases and critical paths are covered. For purely visual components I lean on interactive documentation, which catches an interface regression better than a test frozen on last month's mockup.

And I align with the testing strategy of the team I join: its definition of done becomes mine from the first pull request.

Before writing code

If I can't describe the outcome in one sentence, it isn't ready to be built.

Before writing code, I check that I can describe the expected outcome in one sentence. If I can't, it isn't ready to be built - it's ready to be discussed.

That doesn't mean specifying everything. It means not starting with the easy part and hoping the rest becomes clear along the way.

Shipping to production

Three environments, nothing moves without review, and I watch afterwards.

Dev, staging, production, and nothing moves without a pull request. CI runs on every PR: if it's red, nothing advances.

After a release, I watch. Errors, response times, the path I just touched. A deployment isn't done when the pipeline is green, it's done when nothing moved in the metrics.

Communicating

When a topic dies for lack of the right audience, I carry it elsewhere.

I flag a blocker early and in writing, not at the tipping point. An estimate that slips gets said the day I see it, not the day it's due.

When a spec is vague, I don't guess and I don't wait either: I write down the interpretation I'm going to follow and get it confirmed in one line. It costs two minutes and saves redoing a week.

And when a topic dies because it wasn't raised in the right place, I move it. I once raised publicly a problem many were quietly living with; a lead replied that design needed to weigh in. Rather than let the thread die, I reframed it in the product channel with a message suited to that audience. The same day, another developer opened the pull request.

If you want to dig into any of these points, that's exactly what I'd like to talk about in an interview.

Back to home