Forward-deployed engineering

I don't need to learn your customer. I am your customer.

I'm JD Kemp. I embed with a team, learn the customer's domain fast enough to be useful, and ship the production system that makes the product actually work in their world — the integration, the migration, the prototype that closes the deal, the pipeline that gets ugly data into a usable shape.

Every other engineer up for that work has never run a business. I run a home-services company that depends on software I wrote and still operate. If you sell into trades, home services, clinics or local services, I have quoted the job, chased the invoice, and lost the customer to a booking form that didn't work — this year, with my own money on the line.

That is the hardest thing on your list to hire for, and I have it by accident of biography.

$216K
invoiced through software I wrote and operate
3,235
transactions auto-categorised
~140 hrs
of admin removed from my own week
1
engineer — nothing to production is somebody else's job

Those four are the only numbers I claim. There is no client count, no satisfaction score, and no team — and where a figure would flatter me but isn't true, it isn't here.

Scope it in thirty seconds

Tell me the shape of the problem. I'll tell you if I'm the wrong person.

Four questions, then a real engagement brief you can forward to whoever signs off — including the cases where the honest answer is that you need someone else.

Engagement scoper

01What’s actually stuck?
02Whose world is it?
03Over what window?
04What worries you most about bringing someone in?

This runs entirely in your browser and there is no model behind it — the same four answers always produce the same brief. That is deliberate: an LLM verdict is not reproducible and cannot be audited afterwards, which is the same rule I apply to the scoring and ranking code below. Nothing you tap is transmitted anywhere.

Read the code

Three things I built, and the decisions inside them

Not a list of technologies. The small number of decisions everything else followed from, and whether the code actually enforces them.

01

Multi-tenant clinical platform

Many separately branded clinics on one deployment — storefront, patient portal, clinic CRM and webhook ingest across four subdomains. 95 TypeScript source files, 29 test files, 36 migrations.

Built and owned by me. It has no live client, and I will not imply otherwise.

View on GitHub →
  • Tenant isolation in PostgreSQL row-level security, not application code. A query that forgets its WHERE clause returns nothing rather than another clinic's patients.
  • A clinical-network adapter behind a typed boundary, so the vendor can be swapped without touching anything downstream. That decision is what made it a product rather than custom work.
  • Per-service IAM and RDS IAM auth — no long-lived database passwords anywhere in it.
02

A public endpoint that fetches arbitrary URLs

The free audit on this site runs headless Chromium in Lambda against any address a stranger types into a form. Unauthenticated, public, and pointed at whatever you give it.

Security judgement on a public endpoint is what an FDE gets trusted with on day one in someone else's environment.

Try it →
  • That shape is an SSRF liability unless the boundary is real: link-local metadata (169.254.169.254), RFC1918 and CGNAT ranges, credentials embedded in the URL, non-HTTP schemes, and .internal/.local names are all refused.
  • DNS is resolved and checked before the fetch, because a public hostname can point at a private address and a URL allowlist alone would never catch it.
  • 36 tests against that boundary — 24 blocked inputs, 11 that must still be allowed, and a bounds check — run against the guard rather than a local mock.
03

An end-to-end prospecting pipeline

Google Places → enrichment → headless audit → scoring → CRM. It is how I find my own clients: 3,000+ businesses swept, scored and loaded, with the compliance rules encoded in the scorer rather than left to whoever runs it.

It also shows I build tools for myself first, which is the instinct the job runs on.

View on GitHub →
  • Ranking runs in code with no model call, so the same input produces the same output. An LLM verdict is not reproducible and cannot be audited after the fact.
  • Idempotent writes keyed on place_id, a do-not-contact gate, and suppression applied at scoring time so a do-not-solicit address never reaches the CRM at all.
  • Every importer dry-runs by default and needs --commit said out loud to touch production.

The part most portfolios leave out

Three bugs that only appear in production

I would rather you judge me on these than on a feature list. Each one cost real hours, and in every case the error message named the symptom and not one component involved in causing it.

Symptom

"empty password returned by client" on every database connection

Cause

node-postgres was silently discarding the IAM token function. The connection string was parsed into an object and merged with Object.assign, which let the parsed URL's empty password field overwrite the function that generates the token.

What it changed

The error named the symptom and not one component involved in causing it. Config merge order is worth reading twice when a credential is a function rather than a string.

Symptom

Two services permanently unhealthy, with a health check that looked fine

Cause

The readiness probe called a dependency the service's own IAM role forbade. The probe failed, so the task never went healthy, so it was replaced — forever.

What it changed

A readiness probe should assert what the service needs to serve traffic, not everything it might eventually touch. Probes that over-reach turn a permissions problem into a crash loop.

Symptom

ECS Exec silently unavailable, with no reason given anywhere

Cause

readonlyRootFilesystem stopped the SSM agent from writing where it needs to. Nothing logged it; the exec attempt just failed.

What it changed

Hardening and debuggability trade against each other, and the trade should be a decision rather than a surprise discovered at the worst moment.

The stack

Whole-stack, which is the job

Languages — TypeScript, Python, JavaScript.

Frontend — React, React Native, Next.js, Expo.

Backend and data — Node, Lambda, API Gateway, DynamoDB, PostgreSQL/RDS, ECS.

Infrastructure — AWS, Terraform, CDK, Cognito, SES, CloudFront, IAM.

AI — Claude in production, and the evaluation layer that decides whether an answer is good enough to show anyone.

Breadth over depth is deliberate. On an embedded engagement you touch their auth, their database, their frontend, their deploy pipeline and someone's spreadsheet, usually in the same week.

How an engagement runs

Short, scoped, and yours at the end

Weeks, not quarters. A defined stretch against a named outcome. If the outcome turns out to be the wrong one, I would rather say so in week one than bill through to the end of it.

On your real data. A demo that works on clean input has proved nothing. Their data is bad, the API is undocumented, and the stakeholder changes their mind — that is the work, not an obstacle to it.

Documented so it outlives me. An embedded engineer who leaves behind something only they can operate has made the problem worse.

I talk to non-engineers without condescension. Half the job is sitting with an operations manager and working out what they actually do all day. I have been the operations manager.

Available for embedded contracts

If you have a customer engagement that needs someone who can learn their world fast and ship into it, tell me about the customer and what "working" would look like. If I am not the right person for it I will say so, and it costs you one email.

If you are a developer rather than someone hiring one, I also run a school — Hood Dev, which teaches the messy half of this job. Free while I build it.