Modern tools. Unchanged standards.
We use modern AI tools to take the repetitive work off our engineers, so their time goes into architecture, security, and review. The standards don’t move. Every line is owned by a person who can explain it.
What AI actually changes
Where it genuinely helps
AI is good at the mechanical middle of the job: setting up services, drafting tests, proposing migrations, writing documentation, and handling large refactors. This is work that used to eat a large part of an engineer’s week and rewards speed more than judgment.
Where it changes nothing
It doesn’t decide your architecture. It doesn’t choose a data model, sign off on a security review, or judge whether a trade-off suits your business. Those calls need context and accountability that no tool carries. Our engineers make them, exactly as they did before.
AI moved the typing. It did not move the thinking, and it never moves the responsibility.
We treat AI tools the way we treat cloud.
We work across AWS, Azure, and Google Cloud and choose the one that fits your business, your stack, and your constraints. We don’t push a favourite and we don’t lock you in. Our view of AI tooling is exactly the same.
Our engineers are hands-on across the major assisted-development tools. Which one we reach for depends on the task, the toolchain you already run, and above all your policy. If your security team has approved some tools and not others, we work inside that list. If they’ve approved none, that’s a supported way of working too.
Most of our work runs through Claude Code, so it’s the clearest example to walk through. The guardrails below apply whichever tool is in play.
How we use Claude Code
What it does
- Sets up services, modules, and boilerplate to our internal patterns
- Drafts tests, which an engineer then reviews and extends
- Proposes migrations, which a human approves or rewrites before they run
- Handles large mechanical refactors, in reviewable steps
- Writes documentation, runbooks, and API references
- Explains legacy code, so modernization starts from understanding
What it never does
- Touch production. Ever.
- Read production databases or live customer data
- See secrets, API keys, or .env files, excluded at the tool level
- Merge its own work, approve a pull request, or skip a review
- Run destructive commands unattended
- Make an architecture, schema, or security decision without an engineer owning it
How we keep it safe
Secrets and keys
The risk: The fastest way to leak a credential is to let a tool read a file it never needed.
Secrets live in a manager such as Vault, AWS Secrets Manager, or Doppler, never in the repo. AI tools are configured to exclude .env, credential files, and infrastructure directories by design. We prefer short-lived, role-based credentials over static keys, and run secret scanning (gitleaks, TruffleHog) as a pre-commit hook and a CI gate, so a commit carrying a key can’t reach the branch.
Database schema and migrations
The risk: A generated migration that looks right and quietly loses data.
Schema is a human decision. An engineer models the data around how it will really be queried and owns that design. A tool may draft a migration; it never runs one. Every migration is versioned, reversible, peer-reviewed, and rehearsed against a copy of the data before it goes near production.
Your data
The risk: Sensitive data ending up somewhere it shouldn’t.
Development and testing run on synthetic or masked datasets. Real customer data doesn’t enter a developer environment, so it never enters a tool’s context. Where a task needs production-shaped data, we generate it, same schema, same edge cases, none of the people.
Code review
The risk: Code nobody actually understands reaching production.
Every change, AI-assisted or not, goes through the same pull request, the same reviewer, and the same standard. An engineer must be able to explain and defend every line they submit. Code nobody can defend does not merge.
The pipeline
The risk: Speed quietly eroding quality over months.
Quality is enforced by machines, not memory. Every commit runs linting, type checking, static analysis, dependency and vulnerability scanning, and the test suite. Coverage thresholds block a merge. Security findings block a merge. The gates are identical whether a human or a tool drafted the change.
Dependencies
The risk: A generated import pulling in an unvetted package.
Dependencies are pinned and lockfiles committed. New packages need review. Automated scanning flags known vulnerabilities on every build, and we produce an SBOM where you need one.
The standards underneath
Modern tooling drafts a great deal of the mechanical middle of the job, and it drafts it well. What it cannot do is tell you whether the thing it drafted is the shape you want to be living with in three years.
That judgement is the whole of what an experienced engineer is for, and it is worth being specific about what it consists of rather than gesturing at seniority.
Architecture and coding standards are decisions
If they are not made at the start, they get made anyway. They get made accidentally, thousands of times, by whoever is closest to the deadline, and every one of those small decisions looks reasonable on the day it is taken.
Nothing errors. Nothing fails review. The code works, the tests are green, and the cost arrives later as something that looks like an infrastructure problem, a performance problem, or a delivery problem, long after anybody can point at where it came from.
So we agree the standards before the work rather than discovering them during it, and the four below account for most of the difference.
Boundaries are a commercial decision, not an aesthetic one
The most common version of this is a platform that talks to several external providers of the same thing, none of which agree on how it should be delivered.
The direct version works. Each module talks to each provider, and on the day it ships it is indistinguishable from the alternative. The version with a boundary also works, and puts one adapter in front of each provider so that everything downstream reads one internal shape.
The difference is not visible until something moves. A fourth provider arrives, or a field changes, or somebody needs to know which parts of the system will break. In the first version that is a project. In the second it is an adapter and a set of tests.
That is dependency inversion, and stating it as a principle undersells it. Which provider a prospective customer happens to use stops being a qualification question, which is a sales conversation rather than a code review conversation. The principle earns its place because of what it does to the business, not because of what it does to the diagram.
The same reasoning applies to any capability a platform does not own: payment providers, identity checks, mapping, messaging, model vendors. The question is never whether the integration works. It is what has to change when the second one arrives.
Everything that is held has an owner and an end
Anything holding a connection, a file handle, an event listener, or a buffer has to have someone who owns it and an event that ends it. If either half of that is a shrug at review time, the code is not finished, however well it runs today.
This is the category that automated gates are worst at. A listener registered when a component appears and never removed when it goes. A connection opened for a query and held for the length of a request that then waits on something slow. An anonymous closure that captures the object graph around it and outlives the thing it was written inside. A cache with no eviction, or a collection appended to per event and keyed by something unbounded.
Every one of those is correct code. Linting will not find them, type checking will not find them, and the test suite is green, because a test never runs long enough for unbounded to mean anything.
They are found by somebody who has seen them before, reading the code and asking who owns this and what ends it. At low volume they are tidiness. At scale they stop being tidiness and become the largest line in the bill, arriving labelled as infrastructure.
What a module knows is what it is coupled to
A module that reads what it needs is one you can change. A module that reads what happens to exist is one that breaks when something unrelated moves.
The practical version is that interfaces are defined by the consumer’s need rather than by the producer’s convenience, and that a component receives what it requires rather than reaching for what is available. Both of those are ordinary discipline until a system is large enough that no single person holds all of it, and then they are the difference between a change that takes an afternoon and a change nobody wants to make.
There is a second consequence that matters more than the maintenance one. A boundary enforced structurally is inherited by features that have not been written yet. A rule that lives in the data layer applies to the next screen automatically. A rule that lives in a convention applies until somebody forgets. In anything holding sensitive data, that distinction is the difference between a control and a training slide.
The hot path is where correct becomes expensive
Most code runs rarely enough that ordinary choices are the right ones, and premature optimisation is a real failure mode rather than a slogan.
But every system has a small number of paths that run millions of times, and on those the calculation inverts. A structure that regrows as it fills, work repeated per record rather than per batch, an allocation inside a loop that could have sat outside it: at low volume these are invisible and correct. At high volume they are paid for on every run, every night, and they never appear as a line item because they arrive labelled as infrastructure.
Knowing which paths are hot before writing them is experience. Finding out afterwards is a bill.
How standards hold
None of this survives on discipline alone, which is why the machinery described above exists.
Formatting, linting, type checking, and static analysis are enforced by the pipeline rather than by memory, and coverage thresholds and security findings block a merge whoever or whatever drafted the change. That removes the mechanical half from human attention entirely.
What is left is the half a gate cannot check: whether the boundary is in the right place, whether a resource has an owner, whether this path is hot, and whether the shape of the thing will still make sense when somebody else is holding it. That is what review is actually for, and it is why every change has a named engineer who can explain and defend it.
A tool can draft a module that reads one provider directly. It works, it passes review, and it is indistinguishable from the right answer until the fourth provider arrives. Knowing which of the two you are looking at, before either is written, is the part that does not come from a tool.
The same argument, with a cost figure attached, is in our case studies.
If you’d rather we didn’t use AI at all
Some clients work under rules, or preferences, that put AI tooling out of scope. That’s a fair position, and we support it in writing rather than by promise.
AI-accelerated
DefaultModern tooling used inside the guardrails above, under enterprise terms with retention disabled. Fastest delivery, standards unchanged.
Restricted context
ScopedAI tooling allowed but scoped: no proprietary business logic, no regulated code paths, no client repositories in context. Used only on isolated work like tests, docs, and scaffolding.
AI-free
Human-onlyNo AI tooling touches your codebase. Fully human engineering, guaranteed as a contract addendum, and auditable. We adjust timelines honestly and tell you what the difference is up front.
Whichever tier you choose, the same commitments hold. Your code and data stay inside your boundary or ours as agreed, never in a public tool, never in a consumer account, and never used to train anyone’s model. We’ll work inside your cloud or VPC where you need it, and sign a DPA that says so.
We’re not going to claim a multiple.
The gain shows up in lead time, how long a change takes to go from agreed to live, not in lines of code per day. Setup, tests, migrations, refactors, and documentation move much faster. Architecture, security review, and design decisions take exactly as long as they always did, because rushing those is how projects fail.
The net effect is that our engineers spend far more of their week on the work that actually needs a human. That’s where the speed comes from. The standards didn’t get lighter, the busywork stopped eating the people who should be thinking.
If going faster meant shipping code nobody understands, we’d go slower. That’s not a slogan. It’s why the review gate has no exceptions.
What we hold ourselves to
Engineering claims are cheap, so we split ours in two. The four delivery measures are things we measure and report to you. The six quality and security commitments are enforced by the pipeline and true on every engagement, whoever or whatever drafted the change.
Delivery
Quality and security
If a measure matters to you and isn’t here, tell us and we’ll track it.
Why these are the measures
The commitments above are not a list we assembled for a marketing page. They are the questions an auditor asks, answered in advance.
The SOC 2 trust services criteria come down to a small number of things: who can reach what, whether changes are controlled, whether the system does what it claims completely and accurately, whether it is there when it is needed, and whether any of that can be evidenced afterwards. Human review with a named owner, secrets held outside the repository, coverage and scanning enforced by the pipeline, synthetic data in development, and a tested way back on every release are the ordinary engineering answers to those questions.
Designing against the criteria from the start is a different exercise from mapping to them afterwards. An organisation that did the first is documenting controls that already exist. An organisation that did the second is retrofitting them under time pressure, usually while engineering stops, and assembling evidence after the fact for controls that were not in place during the period being examined. The difference is measured in quarters and in consultant fees.
What that looks like in practice
The criterion that matters most is rarely the one people expect, and it changes with the platform. Four examples from work we have done.
On a platform where competitors share the infrastructure, the question is confidentiality, and the usual answer is a tenant column on every table. That holds only as long as every query in every module remembers it, and when one does not it returns more rows rather than an error. Isolation as a structural property means a query that forgets its filter has nothing else to return.
On a platform where money moves on every action, the criterion is processing integrity. A charge must correspond to something that happened, at the cost actually incurred, and a margin figure must reconcile to the activities behind it rather than to an average. Cost recorded at the moment of the action rather than recalculated later from a price list that has since moved is what makes that possible at all.
On a platform serving a market that opens at a fixed time, it is availability, and not as a percentage in a service agreement. A system unavailable at the open has not degraded, it has failed for the day, and there is no rescheduling it. That reframes decisions that look like cost optimisation, because a rate limit reached at the busiest minute is an outage.
On a platform holding data about people who never signed up, it is privacy. The criterion concerns the people the data is about and what say they have over it, and on some platforms the largest group of data subjects have no account and never agreed to anything. That is a design constraint rather than a compliance technicality, and it is why those platforms hold as little as they can and join it as late as they can.
What we do not claim
We design control sets against the criteria. We do not hold an attestation on any client’s behalf, and we cannot.
SOC 2 is an audited report covering a defined period, issued by an audit firm to a named organisation. A supplier cannot hold one for somebody else, and a supplier who implies otherwise is making a claim their client will eventually be asked to evidence.
Where you need an attestation, the audit is yours to complete with a firm you appoint. What we can do is make sure that when you start, the controls are already in place and the evidence already exists, so the exercise is documentation rather than remediation.
The same applies to every other framework. We build to the standards your regulator or your customers require, and we do not claim certifications we do not hold.
Engineering FAQ
Does AI write our code?
It drafts parts of it: setup, tests, migrations, refactors, docs. Every line is then reviewed, and often rewritten, by the engineer who signs their name to it. Nothing merges that a person can’t explain.
Could our source code be used to train a model?
No. We work under enterprise terms with retention disabled and never use consumer AI accounts for client work. If you want that in the contract, we’ll put it there.
Do your tools ever see our production data?
No. Development runs on synthetic or masked data, so real customer records never reach a developer environment.
How are keys and credentials protected?
They live in a secrets manager, never in the repo. Credential files are excluded from AI tools at the tool level, and scanning blocks any commit carrying a key.
Can we opt out of AI tooling entirely?
Yes. It’s a contractual commitment, not a verbal one, and we’ll be straight about what it means for the timeline.
Does moving faster mean lower quality?
The gates don’t change. Coverage, static analysis, scanning, and human review apply to every change however it was drafted.
Can you work inside our cloud, VPC, or on-prem?
Yes, where your policy needs it.
Who is accountable if something breaks?
Every change has a named owner, and we remain accountable for how the system behaves in production for the duration of the engagement and any support arrangement that follows.
Want to see the standards before you commit?
We’ll walk you through our practices, our AI use policy, and the guardrails in detail. And if you’d rather we didn’t use these tools at all, we’ll tell you exactly what that changes.