Case study · Proof: application

Deal-Flow Infrastructure for a Real Estate Acquisition Company

The engagement

I was retained as the embedded AI systems architect for a mobile home park and RV park acquisition company. They needed to screen inbound deals fast, make sure deals sellers submitted actually reached the principal, and build the off-market sourcing and intake around it. I planned and specced each system, built it with Claude Code, and deployed it. The company runs the systems themselves. I am not in the loop for routine use.

The outcome

The company can take a raw stack of deal documents and get a defensible buy, hold, or pass read in a few minutes for under a dollar. Deals that sellers submit route straight to the principal with an automatic acknowledgment back to the seller, and an off-market sourcing pipeline surfaces the park owners the public listing sites miss. The deal analyzer alone went from $8.00 per analysis to about $0.60, and got more accurate in the process.

Analyzer report header: property snapshot, verdict box, and the ceiling statement for the deal.

Hero system: the deal analyzer

What was actually going on

A non-technical buyer was receiving deal packets (offering memos, trailing-twelve financials, rent rolls, utility bills, leases) that never agree with each other. The offering memo is optimistic, the actuals tell a different story, and the numbers are scattered across formats. Reading each packet by hand is slow. The fast way, pasting everything into one AI prompt and asking for a verdict, is the reliable way to get a confident wrong answer.

The first version I built did exactly that. It cost $8.00 per run, and it reported a different NOI in the metrics, in the offers, and in the cap-rate math on the same deal. That failure defined the real problem. The financial math cannot live inside a model that is free to say something different each time it renders.

What I decided, and what I ruled out

This is the part that matters. Each decision is the path I took and the plausible path I rejected.

  • Rejected the single mega-prompt. I split the work into a staged pipeline where each stage does one job and passes structured data forward. Parse, reconcile, compute, evaluate, structure, assemble. Four AI calls, two deterministic code steps.
  • Rejected letting the model do the math. The model reads the documents and extracts the numbers. Plain code compares the sources, decides which to trust, and computes NOI and the metrics once. This is the load-bearing decision of the whole build. Model wording can change. The math cannot.
  • Rejected trusting whatever number got extracted first. A reconciliation step compares every source against the others and selects what to trust on a fixed hierarchy, where actual trailing-twelve financials outrank an optimistic offering memo, and it flags where sources disagree.
  • Rejected a tool that always answers. When the documents are thin or contradictory, it grades its own confidence and returns a provisional verdict instead of a number it cannot stand behind.
  • Rejected one model for every job. Parsing and structuring run on a mid-tier model. The one judgment stage, market research and red flags, runs on the strongest model with web search. The report write-up runs on the cheapest model. Output volume is the primary cost driver, so putting the cheap model on the writing is where most of the savings came from. Staging plus this split is what took a run from $8.00 to about $0.60.
  • Rejected paying for the client's runs. The tool accepts the client's own API key. They own their runtime cost and their data, and I am not a cost bottleneck sitting between them and their own tool.

Where this could break

The most serious failure I found in this tool wasn’t in the financial logic. It was one layer upstream, in the code that turns a PDF into text the model can read. A silent truncation bug was cutting the last few digits off every dollar figure it converted, on every document, for months. On one deal it turned an intact, internally consistent offering memo into a false CRITICAL red flag against the broker: the tool accused them of a rent-roll duplication that only existed in my own converter’s output, not in their document. The broker was right. My pipeline was wrong, and it said so with full confidence.

I found it the way I want to find these things: I checked the tool’s numbers against the original source documents myself, before I trusted them enough to put on this page. That check became a full ground-truth audit, and it surfaced six more failures of the same shape, wrong classification decisions rendered with total confidence, not wrong arithmetic. The closest call came about an hour before I’d planned to ship this page. A step that’s supposed to total a client’s utility bills was instead multiplying them by twelve, turning a real $11,460 into a reported $137,522, on the exact panel I’d picked for the screenshot. I caught it because the number looked too clean to be real, traced it back to the bills, and fixed it before anything went out.

It was validated end to end mostly on one asset type. The RV path shares the same code but has had less real-world testing, and that’s still the next thing I’d harden before leaning on it for that deal type.

One more honest limit. The company runs its deal-submission routing and its website day to day without me in the loop. The analyzer is proven, not yet adopted into that same daily routine, so I can’t point to months of unattended runs on it the way I can for the rest of this system.

NOI reconciliation panel from the analyzer report: a two-number breakdown and a normalization delta table.

What holds. What moves. On purpose. Five runs of the full pipeline, same input documents, same six source files, no changes in between:

RunNOI (code)Cap rate (researched)Income-approach value
1$55,6728.75%$636,251
2$55,6729.5%$586,021
3$55,6728.5%$654,965
4$55,6729.0%$618,578
5$55,6728.5%$654,965

NOI never moved. It’s computed once in code from the anchored source documents, so there’s nothing left in the pipeline free to say it differently on the next run. The cap rate is the one number in this report that’s supposed to move: it’s live-researched market data, not a fact about the deal, and it comes back a little different depending on when you ask and what’s changed in the comparable set that week. Every run cites its own sources and date. The income-approach value is never a separate guess. It’s NOI divided by whatever that run’s cap rate came back as, to the dollar, every time.

What changed

Same stack of documents, a few minutes, about $0.60, and a verdict the buyer can defend. NOI is consistent across every section of the report, and the weak spots are flagged instead of smoothed over. The first build proved the trap. The staged, code-decides build is what made the tool both trustworthy and cheap enough to run on every inbound deal. Total build time was roughly 8 to 10 hours, most of it spent on the numbers-consistency troubleshooting, not the wiring.

Since the audit, I built the thing I wish I’d had from day one: a ground-truth answer key derived independently from the original source documents, not from the tool’s own past output, and 260 tests that run against it before every deploy, 220 checking the deterministic code paths and 40 checking the numbers against that key. A separate harness re-runs just the document-reading stage on its own and checks every number it extracts against the source text, flagging anything that looks invented rather than read. That harness is what caught the false accusation before this page went up.

Deal analyzer setup panel with six source files attached, ready to run.

Supporting systems

Deal submission and routing

Deals that sellers submitted were disappearing into the CRM's default owner assignment and never reaching the principal. Worse, a stock outreach workflow that shipped with the account was auto-emailing cash offers and bot-texting the very sellers who had just filled out the form. For a company whose entire brand is patient, long-haul ownership rather than fast-cash wholesaling, its own system spamming sellers with cash offers was a real credibility risk. I rebuilt the intake so a submission creates the contact, tags it, logs the full property detail, sends the seller a genuine acknowledgment by text and email, and notifies the principal and operator directly. Then I shut off the rogue outreach. Competency shown: workflow reliability and brand-risk cleanup inside a messy inherited system.

Off-market sourcing

The public listing sites miss most small parks, and the owners sit behind LLCs. I built and proved out a pipeline that pulls off-market park lists through a major listing platform's public API, resolves the owner and the LLC behind each parcel through skip-tracing data, and classifies every phone number as landline or mobile through a carrier lookup so outreach reaches the right line. Competency shown: applied data engineering and public-records enrichment.

Website and intake front door

The brand website and the submit-a-deal page host the form that feeds the routing system. Supporting scope: the entry point to everything above.

What I'd do next

Validate the RV path against real RV park deals with the same rigor the MHP path already has, and add a lightweight check on the extraction stages so a bad parse is caught by a test, not only by the sanity bands.

Rather ask than read? The agent answers from this piece and the other case studies, and it says so when the answer is not in them.

Tell me what you’re dealing with.

You don’t have to take a meeting to find out if I can help. Send a note about where your company’s knowledge gets stuck, and I’ll tell you what I see and whether I think I’m the right fit. If you’re a one-person shop and all the knowledge is yours, you don’t need this yet, come back when you’re hiring.

Tell me what you’re dealing with

A few quick questions so I understand your situation before I reply. No meeting required, and I read these myself.

Would you rather I reply in writing, or set up a short call?