Core Principle
All market data (counties, parcels, pricing, due diligence) is real.
Only the customers (buyers, sellers, competitors) are simulated.
This means the pipeline machinery is tested against real-world data before a single real customer interaction.
SIMULATION ONLY Disabled in production
BOTH MODES Runs in sim & prod, stamps data
PRODUCTION ALWAYS Never checks mode
SIM → PROD LATER Sim-only now, will become prod (green-orange gradient border)
Real Data Factual market/parcel data
Simulated Data Fake customer behavior
STAGE 1
County → Parcel → Priced
countyScout
➔
🗃 counties
score, grade, tier
➔
parcelHunter
➔
🗃 parcels
status: candidate
➔
pricer
➔
🗃 parcels
status: priced
offer_price set
Data sources: LandWatch + LandAndFarm (comps/scoring) | Bulk CSV imports | Gemini AI scoring
STAGE 2
Seller Outreach (Mail + Postcards)
🗃 parcels
status: priced
➔
USPS
address verify
➔
outreach
➔
🗃 outreach_touches
is_simulated flag
➔
Click2Mail
➔
🗃 postal_batches
is_simulated flag
3-touch sequence: Letter → Postcard → Certified Letter |
Also: Monthly delinquent batch (1st) + Quarterly EDDM blast (Jan/Apr/Jul/Oct) |
List sources: delinquent_tax, heir, stale_owner, neighbor, eddm, referral
Seller responds via: Email (Brevo inbound parser) | SMS (SignalWire) | Instagram DM (webhook) | Phone call
STAGE 3
Seller Path: Negotiation → DD Gate → Contract → Funding → Deed
Parcel Status Chain
priced→
outreach_sent→
lead_came_in→
contacted→
in_negotiation→
accepted→
In DD→
contract_sent→
contract_signed→
funds_wired→
deed_recorded→
purchased
🗃 parcels
status: In DD
➔
ddCheck
➔
🗃 parcels
dd_check result
dd_defect_discount_pct
DD gate checks: Back taxes, Road access, Flood zone, HOA | Defect discount: up to 50% price reduction | Parcel must pass DD before contract can be sent
verbal
accept
➔
🗃 sellers
➔
offersClosing
title check
➔
BoldSign
e-signature
➔
🗃 deals
contract_sent
contract_signed
⋮
operator
approves
➔
financeServicing
➔
🗃 deals
funds_wired →
deed_recorded →
purchased
➔
🗃 transfers
Mercury → Wise
Deal types:
acquire_flip (buy & sell, owner financing via Stripe) |
acquire_note (buy existing note, collect payments via Stripe) |
wholesale_contract (assign contract, cash, no servicing)
Money flow: Operator approves wire → Mercury receives → Wise disburses |
Owner finance: Stripe subscription (9.5% APR, 60 months, 10% down)
STAGE 4
Lister → All Platforms
🗃 parcels
status: purchased
ready_to_list
➔
lister
➔
🗃 parcels
listing_price (2.5x)
description, terms
acreford_listing_url
➔
Cloudflare
Pages
➔
acreford.com
live site rebuild
⋮
🗃 parcels
status: listed
➔
multiPlatformLister
(sim only)
➔
🗃 simulated_listings
A/B copy per platform
acreford.com
Cloudflare Pages
REAL + SIM
Facebook Marketplace
multiPlatformLister
SIM ONLY → PROD LATER
Craigslist
multiPlatformLister
SIM ONLY → PROD LATER
LandHub
multiPlatformLister
SIM ONLY → PROD LATER
LandModo
multiPlatformLister
SIM ONLY → PROD LATER
Instagram DM
webhook listener
REAL + SIM
LandWatch
comps data only
NOT FOR LISTING
LandAndFarm
comps data only
NOT FOR LISTING
STAGE 5
Buyer Reaches Acreford → Matched → Sold
Brevo Email
inbound parser
SignalWire SMS
inbound + outbound
🗃 buyers
preferences: states,
acreage, price, terrain
➔
buyerMatch
score ≥ 40/100
➔
🗃 buyer_matches
email_draft
sms_draft
➔
🗃 pending_approvals
operator approves
outreach
⋮
outreach
sent
➔
Brevo
email
➔
🗃 sms_log
SignalWire
➔
🗃 deals
buyer_inquiry →
buyer_negotiating →
buyer_committed →
buyer_contract_signed →
first_payment →
paying → paid_off
Matching score: State (30) + Acreage (25) + Price (20) + Terrain tags (20) + Road access (5) = max 100, threshold 40, max 10 matches per run
2-way trigger: parcel listed → match all buyers | new buyer created → match all listed parcels
SIM ENGINE
Simulation Engine (green = sim only)
personaGenerator
(weekly)
➔
🗃 simulated_personas
100 fake people
➔
simulationOrchestrator
(every 30 min)
➔
🗃 messages, simulated_calls
fake customer events
⋮
competitionSimulator
➔
🗃 simulated_competing_flippers
➔
dealOutcomeResolver
(daily 11PM)
➔
🗃 simulated_deal_pipeline
stochastic outcomes
➔
🗃 simulated_cash_flow
daily snapshots
VALIDATION & TRAINING
Tracker + A/B Loop + Phone Practice
tracker
(daily + weekly)
validates
promptABLoop
(weekly)
analyzes
operationsManager
(daily + HTTP)
➔
🗃 daily_summaries
KPI narratives
⋮
🗃 simulated_personas
system_prompt, opening_line
➔
🎙 Phone Practice Tool
(v5.1 HTML app)
➔
🗃 simulated_calls
call outcomes
operator trains on
simulated sellers
NEIGHBOR
Neighbor Outreach
parcel
purchased
➔
neighborOutreach
➔
🗃 neighbors
is_simulated flag
frame: consolidation / access / fence_line
PRODUCTION ALWAYS Real data agents that never check mode
Scores counties 0-100 using Gemini + LandWatch/LandAndFarm listing data. Determines which counties to activate for mailing.
counties
LandWatch API
LandAndFarm API
counties (score, grade)
Imports real parcel data from external sources (LandWatch, LandAndFarm, bulk CSV). Scores and creates candidate parcels.
counties
external APIs
parcels
Computes offer prices for candidate parcels using Gemini analysis + rule-based fallbacks. The bridge between hunting and outreach.
parcels
counties
parcels (offer_price)
Runs due diligence (back taxes, road access, flood zone, HOA) using Gemini when a parcel enters "In DD" status. Computes defect discount %.
parcels
parcels (dd_check, dd_defect_discount_pct)
BOTH MODES Runs in sim & prod, stamps is_simulated
Creates 3-touch outreach sequences (letter → postcard → certified letter) for priced parcels. Also handles monthly delinquent batches and quarterly EDDM blasts. Verifies addresses via USPS.
parcels, sellers
outreach_touches (is_simulated)
postal_batches (is_simulated)
Click2Mail API, USPS API
When a parcel is purchased, finds neighboring candidate parcels and generates personalized letters using frame rotation (consolidation / access / fence_line).
parcels
neighbors (is_simulated)
Matches listed parcels to active buyers based on preferences (state, acreage, price, terrain, road access). Generates personalized outreach drafts via Gemini.
parcels, buyers
buyer_matches (is_simulated)
pending_approvals (buyer_match_outreach)
Generates listing descriptions, prices (2.5x purchase), and owner-finance terms (9.5% APR, 60mo, 10% down). Publishes to acreford site via Cloudflare rebuild. In sim mode, also writes simulated_listings.
parcels, counties
parcels (listing_price, description)
simulated_listings (sim only)
Cloudflare Pages API
Runs title check, then sends BoldSign contract envelopes on verbal acceptance. Handles post-signing: funding authorization → funds wired → deed recorded.
deals, parcels, sellers
deals (status transitions)
pending_approvals (funding_authorization)
BoldSign API
Sets up Stripe subscriptions for closed owner-finance deals. Cash deals marked completed. Monthly Mercury → Wise profit transfer reconciliation.
deals
Stripe subscriptions
transfers (Mercury → Wise)
Daily morning briefings, ad-hoc query endpoint, pending approval escalation, weekly failure mode reports.
parcels, deals, pending_approvals
daily_summaries
SIMULATION ONLY Disabled in production
Master controller. Seeds parcels + personas, then generates stochastic events every 30 min during business hours. Creates calls, emails, SMS, postal replies, buyer inquiries, and payment events.
simulated_personas, parcels, deals
messages, simulated_calls
simulated_payments
Generates and maintains ~100 simulated personas (sellers S1-S4, buyers B1-B4) with Gemini-crafted demographics, personalities, and call frequency weights.
simulated_personas (count)
simulated_personas
Creates fake competing land flippers with varying pricing aggressiveness and speed. Feeds competition data into deal pipeline probability adjustments.
counties
simulated_competing_flippers
Resolves deal outcomes stochastically using persona-type probability tables. Seller response rates, acceptance rates, buyer commitment, payment defaults. DD check results adjust probabilities.
simulated_deal_pipeline, simulated_personas
simulated_deal_pipeline
simulated_cash_flow
Generates A/B copy variants for 4 platforms (Facebook Marketplace, Craigslist, LandHub, Landmodo). Currently sim-only. In production, will generate real platform listings with manual approval.
parcels
simulated_listings (8 per parcel) — sim only
real platform listings — after modification
Validates 7 hard business rules (offer caps, road access, county limits, mail caps, follow-up timing, DD requirements, stale cleanup). Archives dead candidates, relists defaults. Currently sim-only — validation logic is already correct, just needs isSimulation() guard removed for production.
parcels, counties
daily_summaries
Analyzes prompt variant performance across outreach letters, neighbor letters, and listing copy. Uses Gemini to recommend which variant works best. Currently sim-only — the A/B framework works on real data too.
messages, neighbors, simulated_listings
daily_summaries
Operator training tool. Simulates phone calls with AI personas so you can practice seller conversations before talking to real people. Loads personas from Firestore, uses Gemini to generate in-character responses. Saves call outcomes back for tracking.
simulated_personas (system_prompt, opening_line)
simulated_calls (outcome, duration, transcript)
Gemini API (live conversation)
⚙ How Each Agent Adapts to Simulation Mode
| Agent |
Mode Check |
Simulation Behavior |
Production Behavior |
| countyScout |
None |
Identical in both modes. Scores counties from real external data. |
| parcelHunter |
None |
Identical in both modes. Imports real parcel data from external APIs. |
| pricer |
None |
Identical in both modes. Computes real offer prices via Gemini + rules. |
| ddCheck |
None |
Identical in both modes. Runs real DD checks via Gemini. |
| outreach |
getSystemMode() |
Creates outreach touches with is_simulated: true. No real mail sent. |
Creates outreach touches with is_simulated: false. Triggers Click2Mail API. |
| neighborOutreach |
isSimulation() |
Creates neighbor records with is_simulated: true. No real letters sent. |
Creates neighbor records with is_simulated: false. Sends real neighbor letters. |
| buyerMatch |
getSystemMode() |
Creates match records with is_simulated: true. No real emails sent. |
Creates match records with is_simulated: false. Sends real buyer emails. |
| lister |
getSystemMode() |
Writes to simulated_listings in addition to normal listing flow. |
Normal listing flow only. Publishes to acreford site + Cloudflare rebuild. |
| offersClosing |
getSystemMode() |
Logs mode. BoldSign integration works the same (or no-op at integration layer). |
Logs mode. Sends real BoldSign contract envelopes. |
| financeServicing |
getSystemMode() |
Logs mode. Sets up Stripe subscriptions the same way. |
Logs mode. Same Stripe subscription setup with real payment processing. |
| operationsManager |
getSystemMode() |
Runs identically. Generates daily briefings from real pipeline data. Mode is logged for context only. |
| simulationOrchestrator |
Hard guard |
Generates fake customer events (calls, emails, SMS, payments) from simulated personas every 30 min during business hours. |
Skipped entirely. Does nothing. |
| personaGenerator |
Hard guard |
Creates/maintains ~100 fake personas (sellers + buyers) with Gemini-generated profiles. |
Skipped entirely. Does nothing. |
| competitionSimulator |
Hard guard |
Creates fake competing flippers with varying aggressiveness in active counties. |
Skipped entirely. Does nothing. |
| dealOutcomeResolver |
Hard guard |
Resolves deal outcomes stochastically using persona probability tables. Writes cash flow snapshots. |
Skipped entirely. Does nothing. |
| multiPlatformLister |
Hard guard |
Generates A/B listing copy for 4 platforms when parcels are listed. |
Skipped entirely. Does nothing. |
| tracker |
Hard guard |
Validates 7 hard rules daily. Archives stale candidates. Relists defaults. |
Skipped entirely. Does nothing. |
| promptABLoop |
Hard guard |
Analyzes prompt variant performance weekly. Generates Gemini recommendations. |
Skipped entirely. Does nothing. |
| 🎙 Phone Practice Tool |
Sim only |
Operator practices phone conversations with AI personas. Surprise mode (random calls) or manual mode (pick persona). Gemini generates in-character responses in real-time. |
Not applicable in production. Training tool for simulation phase only. |
📊 Simulation Data: Where It Lives & Who Creates It
The Simulation Data Rule
Real data = counties, parcels, pricing, DD checks, market listings — factual, from real external sources.
Simulated data = fake customers (personas), their actions (calls, emails), their decisions (accept/reject), their payments, fake competitors.
Simulated data lives in separate collections prefixed with simulated_, or in shared collections with the is_simulated flag set to true.
Simulation-Only Collections (no real data)
simulated_personas
Created by personaGenerator. Consumed by simulationOrchestrator and dealOutcomeResolver.
name, type (S1-S4 / B1-B4), demographics, system_prompt, opening_line, call_frequency_weight, anchor_parcel_id
simulated_calls
Created by simulationOrchestrator and Phone Practice Tool. Records of simulated phone calls — both auto-generated events and operator training sessions.
persona_id, status (ringing/picked_up/declined/missed), duration_seconds, transcript, outcome
simulated_deal_pipeline
Created by simulationOrchestrator. Transitioned by dealOutcomeResolver. Tracks stochastic deal state machine.
state, state_history, persona_id_seller, persona_id_buyer, simulated_offer/purchase/listing/sale_price, outcome_probability
simulated_competing_flippers
Created by competitionSimulator. Consumed by dealOutcomeResolver to adjust acceptance probabilities.
flipper_persona, county, llc_name, pricing_aggressiveness, speed, estimated_monthly_volume
simulated_payments_schedule
Created by dealOutcomeResolver. Simulated payment installments with attempt tracking.
deal_id, buyer_persona_id, scheduled_date, amount, status, attempt_count
simulated_cash_flow
Created by dealOutcomeResolver daily. Financial snapshot of the simulated portfolio.
date, available_cash, monthly_mrr, outstanding_portfolio, cumulative_revenue_6mo, active_deals, active_buyers, defaulted_buyers
simulated_listings
Created by multiPlatformLister and lister (sim mode). A/B copy variants for multiple platforms.
parcel_id, platform, copy_text, variant_label, simulated_buyer_match_rate
Shared Collections (real + simulated data coexist)
messages
Real messages in production. In simulation, simulationOrchestrator adds fake inbound messages with is_simulated: true.
channel, direction, body, is_simulated, simulated_at
outreach_touches
Always created by outreach. In simulation, stamped with is_simulated: true and no real mail is sent.
touch_type (letter/postcard/certified_letter), is_simulated, postal_batch_id
neighbors
Always created by neighborOutreach. In simulation, stamped with is_simulated: true and no real letters sent.
neighbor_owner_name, frame (consolidation/access/fence_line), is_simulated, generated_letter
buyer_matches
Always created by buyerMatch. In simulation, stamped with is_simulated: true and no real emails sent.
buyer_id, parcel_id, match_score, email_draft, sms_draft, is_simulated
daily_summaries
Written by operationsManager, tracker, and promptABLoop. Contains pipeline snapshots and KPI narratives. Same structure in both modes.
date, pipeline_snapshot, kpi_narrative, action_items
Real-Only Collections (no simulation data ever)
counties
Real county data only. Scores from countyScout, listing counts from real APIs.
parcels
Real parcel data only. Imported by parcelHunter, priced by pricer, DD-checked by ddCheck. SimulationOrchestrator reads these to seed simulated events but never writes fake parcels.
sellers / buyers
Real people only. Created when real sellers respond or real buyers sign up. Simulation uses simulated_personas instead.
deals
Real deals only. Created by offersClosing when contracts are signed. Simulation uses simulated_deal_pipeline instead.