---
title: "Four patch points into a system we had never seen"
url: "https://toddpaulbrownjr.com/writing/four-patch-points/"
author: "Todd Paul Brown Jr."
description: "Reverse-engineer an unfamiliar system, then wire a CRM in through four additive patch points with under 80 lines changed and zero edits to existing logic."
kind: "article"
updated: "2026-09-26T02:50:30+00:00"
---

# Four patch points into a system we had never seen

The cleanest integration is the one that looks like it was always there. 

In spring 2026 I led a six-week revenue-operations rebuild for a national amateur sports league: seven systems consolidated, roughly 2,400 teams, zero rollbacks at go-live on 29 May. One deliverable inside that engagement was a HubSpot CRM data mirror that copied team-application lifecycle events out of the league's proprietary registration system. The integration is live in production: a real HubSpot company record created by the integration landed correctly with all three lifecycle stages (initial submission, NDA signed, final approval) over a two-day window, read back from HubSpot's own property-history interface.

The challenge was simple to state: wire a CRM into a live system whose codebase we had never seen, built and maintained by an outside development agency, in a way that would not surprise them when they saw the diff.

## The constraint: additive only

The data mirror is a one-way backend integration copying team-application lifecycle events from the league's registration system — a Python/Django + Celery backend — into a HubSpot CRM I built for them from scratch during the same engagement. I designed and wrote the integration; the registration system's own outside development agency reviewed it, merged it into their codebase and owns deployment.

The specification I wrote for the agency carried one hard constraint: additive only. No edits to existing logic, no assumptions about how their system worked internally, and no trace left if the integration was switched off. The client got a documented integration that their own maintainers could understand and disable cleanly if they needed to.
## Four patch points

The integration landed as four patch points in the registration system's code — three required plus one conditional legacy route — each a small, additive change to an existing file. My documented estimate put the total lines added to existing client code, across all patch points and settings, at under 80 lines.

The four points were:
- A serializer (6–12 lines)
- An e-signature service hook (6–12 lines)
- An insert path for new applications (6–12 lines)
- A model file conditional for a legacy route (6–12 lines)

Each patch point was an explicit hook call at a named location. I chose that over a more "idiomatic" Django signal specifically because the agency maintaining this system had never used a signal in this codebase before. The change would not surprise them.

The integration itself wrapped every HubSpot write in a database transaction commit hook, so a rolled-back save never produced a HubSpot write. Log lines carried only an application ID and an event name — no personal data. Every write was an idempotent upsert keyed on a stable external application ID.

## Built to leave no trace

The integration shipped with two feature flags: one defaults to off, and a separate dry-run flag defaults to on. With the dry-run flag on, the sync logs the payload it would send and exits before calling HubSpot. The system could run with the integration compiled in but completely inert, leaving no side effects.

At the same time I was building this integration, the industry was converging on the idea that the orchestration layer around a model matters as much as the model itself. On 11 March 2025, OpenAI launched the Responses API and Agents SDK, citing customers struggling with custom orchestration logic; two weeks later, on 24 March, a Google Cloud blog post described "agentic orchestration" as a new paradigm for LLM-powered applications to handle complex tasks; and on 9 April, at Google Cloud Next, the company announced ADK and Agent Engine with the line "Every enterprise will soon rely on multi-agent systems." I was building around the same architecture — stable interfaces, explicit control flow, the environment around the integration mattering as much as the integration itself — about the same time the major vendors were naming it.

## Audits left in the code

The integration's shipped code carries three numbered rounds of adversarial audit findings — AUDIT 001, 002, and 003 — left as permanent, dated comments in the source files. Each finding is severity-coded: critical, high, medium, low. At least 3 findings are explicitly marked resolved with a date; 8 remained open as of the last commit I read.

Rather than fixing or hiding the open findings, I left them dated in the code itself. A reviewer six months from now can see what was already known to be unresolved, and decide whether it matters for their context.

A separate, dedicated field-coverage audit caught a data-integrity gap that no functional test had surfaced. The client's front end submitted a field as `web_site`; the receiving code expected `website`. Because the field was optional, the mismatch was treated as simply absent rather than an error, and the value was never stored anywhere — not just never forwarded to HubSpot. 

The gap was found two months after the initial merge, through the field-coverage audit rather than a bug report. No user had complained, because nobody knew the field was supposed to work. The audit found it because it checked coverage, not behaviour.

## What it showed

Reverse-engineer an unfamiliar system into a spec — confirmed, inferred, unknown — then wire in a CRM through four additive patch points with under 80 lines changed and zero edits to existing logic. The integration has been running in production since May 2026. The agency that maintains the system merged it without requesting a single change to the hook locations.

You can wire a new system into a live codebase you have never seen, leave no trace if it is disabled, and hand the maintainers a diff they understand. The trick is to specify what you need the system to tell you, rather than assume you know how it works.
