AgroVar
Published: June 2026
AgroVar - Parametric livestock underwriting intelligence.
The Synergy of Domain Science and Engineering
While modern AI and cloud engineering rapidly accelerate software development, the accuracy of a parametric insurance platform depends fundamentally on specialized domain intelligence. Engineering teams excel at building scalable infrastructure and executing complex syntax. However, determining precise biological realities—such as species-specific thermoregulatory limits, subclinical immune suppression pathways, or multi-day physiological depletion cycles—requires decades of clinical and research experience.
A mathematically flawless model is only valuable if its underlying assumptions are biologically sound. Without deep scientific grounding, parametric models risk mispricing insurance, triggering false payouts, or missing critical mortality events.
The most effective technology ecosystems integrate domain expertise with IT proficiency. The domain specialist defines the vital thresholds, feature engineering, and risk logic, ensuring the model’s output reflects scientific truth. This collaborative dynamic guarantees that the resulting platform remains highly accurate, actuarially defensible, and continuously adaptable to shifting environmental baselines.
1. The Problem: What Livestock Insurance Is Missing
The United States livestock insurance market covers approximately $10 billion in annual premiums across beef cattle, dairy cattle, swine, and poultry. The primary federal products — Livestock Risk Protection (LRP), Livestock Gross Margin (LGM), and Whole-Farm Revenue Protection (WFRP) — are price-based instruments. They protect against commodity price declines. They do not protect against the biological events that actually kill animals and destroy producer income: heat stress, blizzards, drought, and infectious disease outbreaks.
Parametric livestock insurance — products that pay out when a measurable environmental trigger is crossed, without requiring proof of individual animal loss — is an emerging and underserved product category. The concept is sound. The execution is where the industry falls short.
The gap is not data. The gap is biological interpretation.
Weather data is abundant. USDA inventory data is public. RMA loss records are downloadable. The problem is that no existing parametric livestock product has been designed by someone who understands both the insurance mechanism and the biology of why animals die. The result is products with triggers that are either too coarse (a single temperature threshold applied uniformly across species) or too narrow (a single-event trigger that misses the cumulative stress that actually drives mortality).
This system was built to close that gap. It is a livestock biosecurity and parametric risk intelligence platform that combines veterinary science, machine learning, and cloud engineering to deliver biologically grounded risk signals to insurers, underwriters, and producers.
2. The Solution: AgroVar
AgroVar is a full-stack platform with five functional layers:
- Data ingestion — Historical and real-time weather (Open-Meteo), livestock inventory (USDA NASS), and insurance loss records (USDA RMA)
- Feature engineering — Biologically grounded stress indicators: Temperature-Humidity Index (THI), apparent temperature, rolling heat/cold/drought windows, pathogen pressure proxies
- Risk scoring — A species-specific Herd Mortality Risk Index (HMRI) computed by a RandomForest classifier exported to ONNX, served via a FastAPI Cloud Run service
- Backend — Firebase Cloud Functions as a caching proxy layer over Firestore, with 24-hour HMRI cache and 7-day backtest cache
- Frontend — A SvelteKit application with a live Leaflet risk map and an interactive parametric trigger designer
2.1 Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ SvelteKit Frontend │
│ HerdRiskMap (Leaflet) │ TriggerDesigner (Chart.js) │
└────────────────────┬────────────────────────┬───────────────────┘
│ │
┌──────────▼──────────┐ ┌─────────▼──────────┐
│ Firebase Functions │ │ Firebase Functions │
│ getHMRI() │ │ runBacktest() │
│ (24h FS cache) │ │ (7-day FS cache) │
└──────────┬──────────┘ └─────────┬────────────┘
│ │
┌──────────▼────────────────────────▼────────────┐
│ Google Cloud Run │
│ FastAPI · ONNX Runtime │
│ GET /hmri · POST /backtest │
└──────────┬────────────────────────┬─────────────┘
│ │
┌──────────▼──────────┐ ┌─────────▼──────────┐
│ Open-Meteo │ │ Google Cloud │
│ Historical Weather │ │ Storage (GCS) │
│ + Forecast API │ │ ONNX model + data │
└─────────────────────┘ └────────────────────┘
│
┌───────────────────────────────────▼────────────┐
│ USDA NASS + USDA RMA │
│ Livestock inventory · Insurance loss data │
└─────────────────────────────────────────────────┘2.2 Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Data Sources | Open-Meteo, USDA NASS, USDA RMA | Weather, livestock inventory, loss records |
| Feature Engineering | Python (Pandas, NumPy) | THI, HMRI components, rolling stress windows |
| ML Model | Scikit-learn RandomForest + ONNX | Parametric trigger prediction |
| Model Storage | Google Cloud Storage | ONNX model + metadata persistence |
| Backtest API | FastAPI + Docker + Cloud Run | 20-year historical risk analysis |
| Backend | Firebase Cloud Functions (Node 20) | Caching proxy + alert management |
| Database | Firestore | Herd registry, HMRI cache, portfolios |
| Frontend | SvelteKit + Leaflet + Chart.js | Risk map, trigger designer, dashboard |
| Hosting | Firebase Hosting | Production deployment on cytos.dev |
2.3 Monitored Counties
Nine counties were selected to represent the full diversity of US livestock production systems:
| County | State | Species | Avg Herd | Primary Risk |
|---|---|---|---|---|
| Haskell | KS | Beef Cattle | 850 head | Drought / heat |
| Deaf Smith | TX | Beef Cattle | 1,200 head | Drought / heat |
| Custer | NE | Beef Cattle | 950 head | Blizzard / cold |
| Marathon | WI | Dairy Cattle | 450 head | Heat stress / milk loss |
| Tulare | CA | Dairy Cattle | 1,800 head | Heat stress / milk loss |
| Sioux | IA | Hogs | 5,000 head | Respiratory disease |
| Duplin | NC | Hogs | 8,000 head | Respiratory disease |
| Benton | AR | Broilers | 50,000 birds | Heat mortality |
| Hall | GA | Broilers | 45,000 birds | Heat mortality |
Complete Architecture Summary
| Layer | Technology | Purpose | Domain expertise |
|---|---|---|---|
| Data Sources | Open-Meteo, USDA NASS, USDA RMA | Weather + livestock inventory + loss records | Knows which variables matter biologically |
| Feature Engineering | Python (Pandas, NumPy) | THI, HMRI components, rolling stress windows | Features derived from veterinary immunology research |
| ML Model | Scikit-learn RandomForest + ONNX | Parametric trigger prediction | Labels grounded in published mortality thresholds |
| Model Storage | Google Cloud Storage | ONNX model + metadata persistence | Standard MLOps pattern |
| Backtest API | FastAPI + Docker + Cloud Run | 20-year historical risk analysis | REST API design + containerization |
| Backend | Firebase Cloud Functions | Caching proxy + alert management | Serverless architecture |
| Database | Firestore | Herd registry, HMRI cache, portfolios | Domain-correct data schema |
| Frontend | SvelteKit + Leaflet + Chart.js | Risk map, trigger designer, dashboard | Full-stack on existing cytos.dev |
| Hosting | Firebase Hosting | Production deployment | CI/CD via firebase deploy |
Underwriting Portfolio Exposure (Financial Liability)
Metrics: Total Insured Value (TIV), Value at Risk (VaR)
Update Frequency: Real-time
Underwriting Portfolio Exposure
Real-time Total Insured Value (TIV) vs. Probable Maximum Loss (PML) scaled by HMRI.
| Location | Species | TIV | HMRI | Liability Exposure |
|---|---|---|---|---|
| Haskell, KS | BEEF CATTLE | $1,275,000 | 22 | $280,500 |
| Deaf Smith, TX | BEEF CATTLE | $1,800,000 | 65 | $1,170,000 |
| Tulare, CA | DAIRY CATTLE | $3,960,000 | 82 | $3,247,200 |
| Sioux, IA | HOGS | $1,250,000 | 45 | $562,500 |
| Duplin, NC | HOGS | $2,000,000 | 15 | $300,000 |
| Hall, GA | BROILERS | $360,000 | 55 | $198,000 |
3. Phase 0 — GCP and Firebase Foundation
The platform runs on Google Cloud Platform (GCP) with Firebase as the application layer. The GCP project is named mooflux-sentinel (Project ID: mooflux-sentinel-123456), deployed in us-east1 to minimize latency for the primary US livestock belt.
3.1 Project Initialization
# Create GCP project and set billing
gcloud projects create mooflux-sentinel-123456 \
--name="MooFlux Sentinel"
gcloud config set project mooflux-sentinel-123456
gcloud billing projects link mooflux-sentinel-123456 \
--billing-account=YOUR_BILLING_ACCOUNT_ID
# Enable required APIs
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
storage.googleapis.com \
cloudfunctions.googleapis.com \
firestore.googleapis.com3.2 Service Account and IAM
A dedicated service account is created with least-privilege IAM roles. This is a security best practice — the Cloud Run service never runs with owner-level credentials.
gcloud iam service-accounts create mooflux-sentinel-sa \
--display-name="MooFlux Sentinel Service Account"
# Grant only the roles the service actually needs
for ROLE in roles/storage.objectViewer \
roles/datastore.user \
roles/run.invoker; do
gcloud projects add-iam-policy-binding mooflux-sentinel-123456 \
--member="serviceAccount:mooflux-sentinel-sa@mooflux-sentinel-123456.iam.gserviceaccount.com" \
--role="$ROLE"
done3.3 Cloud Storage Buckets
Two GCS buckets are provisioned: one for trained ONNX models and one for processed data artifacts.
gsutil mb -l us-east1 gs://mooflux-sentinel-models
gsutil mb -l us-east1 gs://mooflux-sentinel-data3.4 Firebase Initialization
Firebase is initialized in the SvelteKit project root, selecting Firestore, Functions, Hosting, and Storage. Functions are written in Node.js 20. The hosting public directory is set to build — the SvelteKit static output directory.
4. Phase 1 — Livestock Biosecurity Data Pipeline
The data pipeline is the foundation of the platform. It fetches 20 years of historical weather data (2004–2024) for each of the nine monitored counties, computes biologically grounded stress features, and merges in USDA livestock inventory and RMA insurance loss records.
4.1 Weather Data: Open-Meteo Historical API
Open-Meteo provides free, high-resolution historical weather data via a REST API. For each county, the pipeline fetches daily maximum temperature, minimum temperature, mean temperature, precipitation, snowfall, wind speed, and evapotranspiration.
import openmeteo_requests
import pandas as pd
def fetch_county_weather(lat: float, lon: float,
start: str = "2004-01-01",
end: str = "2024-12-31") -> pd.DataFrame:
om = openmeteo_requests.Client()
params = {
"latitude": lat, "longitude": lon,
"start_date": start, "end_date": end,
"daily": ["temperature_2m_max", "temperature_2m_min",
"temperature_2m_mean", "precipitation_sum",
"snowfall_sum", "wind_speed_10m_max",
"et0_fao_evapotranspiration"],
"timezone": "America/Chicago"
}
responses = om.weather_api(
"https://archive-api.open-meteo.com/v1/archive", params=params)
r = responses[0].Daily()
return pd.DataFrame({
"date": pd.date_range(start=start, end=end, freq="D"),
"tmax": r.Variables(0).ValuesAsNumpy(),
"tmin": r.Variables(1).ValuesAsNumpy(),
"tmean": r.Variables(2).ValuesAsNumpy(),
"precip": r.Variables(3).ValuesAsNumpy(),
"snowfall": r.Variables(4).ValuesAsNumpy(),
"wind_max": r.Variables(5).ValuesAsNumpy(),
"et0": r.Variables(6).ValuesAsNumpy(),
})4.2 Biologically Grounded Feature Engineering
This is where domain expertise becomes irreplaceable. The features computed here are not generic weather statistics. Each one maps to a specific biological pathway that drives livestock mortality and morbidity.
Temperature-Humidity Index (THI)
THI is the standard veterinary measure of heat stress in dairy cattle. It integrates temperature and humidity into a single index that predicts the onset of heat stress physiology — reduced feed intake, elevated respiration rate, decreased milk production, and immune suppression.
# THI formula (simplified, approximating relative humidity from temperature)
# Full formula: THI = 0.8*T + RH/100*(T - 14.4) + 46.4
# Simplified proxy used here (RH approximated at 50%):
df["thi"] = 0.8 * df["tmax"] + 0.5 * (df["tmax"] - 14.4) + 46.4
df["thi_stress"] = (df["thi"] > 72).astype(int)
df["thi_severe_stress"] = (df["thi"] > 80).astype(int)Domain basis: THI > 72 is the established threshold for the onset of heat stress in dairy cattle, associated with a measurable decline in milk yield of approximately 1.5 kg/cow/day per THI unit above 72. THI > 80 corresponds to severe heat stress with significant immune suppression — the TREM-1 pathway, which Dr. Ramanathan cloned and characterized in cattle and pigs, is activated at this level, impairing neutrophil function and increasing susceptibility to secondary bacterial infections.
Wind Chill and Cold Stress
# Wind chill (°C) — standard Environment Canada formula
df["wind_chill"] = (
13.12 + 0.6215 * df["tmean"]
- 11.37 * (df["wind_max"] ** 0.16)
+ 0.3965 * df["tmean"] * (df["wind_max"] ** 0.16)
)
df["cold_stress_day"] = (df["wind_chill"] < -10).astype(int)
df["severe_cold_stress_day"] = (df["wind_chill"] < -20).astype(int)Domain basis: Apparent temperature below -10°C exceeds the thermoregulatory capacity of most livestock species — metabolic heat production cannot compensate for convective heat loss, and feed energy is diverted from growth and production to thermoregulation. Below -20°C, hypothermia risk becomes acute, particularly for neonates and animals with compromised body condition.
Rolling Stress Windows
# Rolling windows — biologically calibrated lookback periods
df["heat_days_7d"] = df["severe_heat_day"].rolling(7).sum()
df["heat_days_14d"] = df["thi_stress"].rolling(14).sum()
df["cold_days_7d"] = df["cold_stress_day"].rolling(7).sum()
df["precip_21d"] = df["precip"].rolling(21).sum() # body condition cycle
df["precip_7d"] = df["precip"].rolling(7).sum() # mud stress cycle
df["et_deficit_14d"] = (df["et0"] - df["precip"]).rolling(14).sum()Domain basis: The 21-day precipitation window is not arbitrary. Body condition score in beef cattle — the primary indicator of nutritional status and drought stress — responds to pasture availability on a 3-week cycle. A 7-day window captures acute mud stress relevant to swine respiratory disease. A 14-day THI window captures the cumulative heat load that drives dairy milk loss, which is a lagged response to sustained thermal stress.
Historical HMRI Trends (Longitudinal Analysis)
Range: 30-Day Trailing
Focus: Critical Asset Monitoring
Historical HMRI Trends (30-Day)
Tracking herd stress fluctuations for critical alert zones.
Blizzard Detection
df["blizzard_day"] = (
(df["snowfall"] > 5) & (df["wind_max"] > 40)
).astype(int)Domain basis: A blizzard event — defined here as snowfall exceeding 5mm combined with wind speeds above 40 km/h — creates two simultaneous threats: hypothermia risk from wind chill, and feed/water access disruption from drifting snow. The combination is more dangerous than either factor alone, which is why the trigger requires both conditions.
5. Phase 2 — The Herd Mortality Risk Index (HMRI) Model
The HMRI is the core scientific contribution of AgroVar. It is a composite risk score, ranging from 0 to 100, that integrates heat stress, cold stress, drought stress, and pathogen pressure into a single actionable number for each monitored county and species.
5.1 Biological Basis of the HMRI
The HMRI is not a statistical artifact. Each component maps to a specific biological mechanism:
| Component | Biological Mechanism | Primary Species Impact |
|---|---|---|
| Heat stress | Hyperthermia → immune suppression → TREM-1 activation → neutrophil dysfunction | Dairy cattle (milk loss), broilers (mortality) |
| Cold stress | Thermoregulatory cost → energy diversion → body condition decline → immune compromise | Beef cattle (weight loss), swine (respiratory disease) |
| Drought stress | Pasture depletion → body condition score decline → reduced immune competence | Beef cattle (mortality), dairy cattle (production loss) |
| Pathogen pressure | Excess moisture → mud stress → respiratory pathogen proliferation → disease outbreak | Swine (PRRS, influenza), broilers (coccidiosis) |
5.2 Species-Specific HMRI Weights
The weights assigned to each HMRI component are not tuned by a machine learning algorithm. They are set by veterinary science and validated against historical loss data.
HMRI_WEIGHTS = {
"BEEF CATTLE": [0.35, 0.20, 0.30, 0.15], # heat, cold, drought, pathogen
"DAIRY CATTLE": [0.40, 0.25, 0.20, 0.15], # dairy more heat-sensitive
"HOGS": [0.30, 0.15, 0.15, 0.40], # swine: pathogen pressure dominant
"BROILERS": [0.50, 0.20, 0.10, 0.20], # broilers: heat mortality dominant
"DEFAULT": [0.35, 0.20, 0.25, 0.20],
}Domain basis: Dairy cattle receive the highest heat weight (0.40) because milk production is a continuous metabolic process that is acutely sensitive to thermal stress — a single day above THI 80 can suppress milk yield for 3–5 days due to the lag in rumen function recovery. Swine receive the highest pathogen pressure weight (0.40) because the primary economic losses in swine production are respiratory diseases (PRRS, influenza, Mycoplasma) that are strongly associated with environmental stress and mud contamination. Broilers receive the highest heat weight (0.50) because heat mortality in poultry is acute — a broiler house without ventilation can lose thousands of birds in hours at temperatures above 35°C.
5.3 HMRI Computation
def compute_hmri(row: pd.Series, species: str) -> float:
w = HMRI_WEIGHTS.get(species, HMRI_WEIGHTS["DEFAULT"])
heat = min(100, (row["heat_days_14d"] / 14.0) * 100)
cold = min(100, (row["cold_days_7d"] / 7.0) * 100)
drought = max(0, min(100, (1 - row["precip_21d"] / 60.0) * 100))
# Pathogen pressure: elevated by ET deficit (dry heat) or excess rain
pathogen = max(0, min(100, (-row["et_deficit_14d"] / 30.0) * 100)) \
if row["et_deficit_14d"] < 0 else 0
pathogen = max(pathogen, row["excess_rain_7d"] * 40)
hmri = w[0]*heat + w[1]*cold + w[2]*drought + w[3]*pathogen
return min(100, max(0, round(hmri, 1)))HMRI alert levels map directly to operational response thresholds:
| HMRI Range | Alert Level | Operational Response |
|---|---|---|
| 0–25 | Normal | No action required |
| 25–50 | Watch | Monitor closely; review feed and water access |
| 50–75 | Advisory | Implement biosecurity protocols; notify veterinarian |
| 75–100 | Critical | Trigger parametric insurance payout; emergency response |
5.4 RandomForest Model and ONNX Export
The ML model predicts whether a parametric trigger condition will be met, given the current feature set. A RandomForest classifier was chosen over deep learning for three reasons: interpretability (feature importances map back to biological mechanisms), robustness on tabular data with ~36 features, and compatibility with ONNX export for lightweight inference on Cloud Run.
from sklearn.ensemble import RandomForestClassifier
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
clf = RandomForestClassifier(
n_estimators=300, max_depth=14,
min_samples_leaf=8, class_weight="balanced",
random_state=42
)
clf.fit(X_train, y_train)
# Export to ONNX for lightweight Cloud Run inference
initial_type = [("float_input", FloatTensorType([None, X_train.shape[1]]))]
onnx_model = convert_sklearn(clf, initial_types=initial_type)
with open("hmri_model.onnx", "wb") as f:
f.write(onnx_model.SerializeToString())The model is trained on data from 2004–2021 and evaluated on a held-out test set from 2022–2024. This temporal split is intentional — it tests the model’s ability to generalize to future conditions, not just interpolate within the training period.
Secondary Perils Matrix (Exogenous Adjustments)
Metrics: Biological Pathogens, Market Volatility
Application: Post-Inference
Secondary Perils & HMRI Adjustment
Market volatility and biological pathogen multipliers applied to the base HMRI.
| Location | Active Secondary Peril | Multiplier | Base HMRI | Adjusted HMRI |
|---|---|---|---|---|
| Haskell, KS | Bovine Viral Diarrhea (BVD) Alert | 1.15x | 22 | 25 |
| Deaf Smith, TX | Feed Corn Price Spike (+20%) | 1.08x | 65 | 70 |
| Tulare, CA | Avian Influenza (Spillover Risk) | 1.25x | 82 | 100 |
| Sioux, IA | PRRS Regional Alert | 1.30x | 45 | 59 |
| Duplin, NC | Hurricane Flooding / Waste Runoff | 1.40x | 15 | 21 |
| Hall, GA | Highly Pathogenic Avian Influenza (HPAI) | 1.50x | 55 | 83 |
6. Phase 3 — Cloud Run Backtest API
The backtest service is a FastAPI application containerized with Docker and deployed to Google Cloud Run. It exposes two endpoints: /hmri for real-time risk scoring and /backtest for 20-year historical trigger analysis.
6.1 FastAPI Service Architecture
from fastapi import FastAPI
import onnxruntime as rt
import numpy as np
app = FastAPI(title="MooFlux Sentinel API")
# Load ONNX model at startup — not per-request
@app.on_event("startup")
async def load_model():
app.state.session = rt.InferenceSession("hmri_model.onnx")
@app.get("/hmri")
async def get_hmri(lat: float, lon: float, species: str):
features = await build_features(lat, lon, species)
inputs = {"float_input": np.array([features], dtype=np.float32)}
outputs = app.state.session.run(None, inputs)
hmri = float(outputs[0][0])
level = get_alert_level(hmri)
return {"hmri": hmri, "alert_level": level, "species": species}
@app.post("/backtest")
async def run_backtest(payload: BacktestRequest):
results = await compute_backtest(
payload.lat, payload.lon, payload.species,
payload.trigger_type, payload.threshold,
payload.window_days, payload.start_year, payload.end_year
)
return results6.2 Docker and Cloud Run Deployment
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]# Build and push container
gcloud builds submit --tag gcr.io/mooflux-sentinel-123456/mooflux-sentinel-api
# Deploy to Cloud Run
gcloud run deploy mooflux-sentinel-api \
--image gcr.io/mooflux-sentinel-123456/mooflux-sentinel-api \
--region us-east1 \
--memory 512Mi --cpu 1 \
--timeout 300 \
--concurrency 10 \
--min-instances 0 --max-instances 3 \
--no-allow-unauthenticated \
--service-account mooflux-sentinel-sa@mooflux-sentinel-123456.iam.gserviceaccount.comCloud Run is configured with minimum instances set to zero — the service scales to zero when idle, keeping costs near zero for a demo-scale deployment. At production scale, minimum instances would be set to 1 to eliminate cold start latency.
AgroVar risk inference (Inference Engine)
Model: Random Forest (ONNX)
Inputs: 36-Point Environmental Vector
Parametric livestock underwriting intelligence.
Execute the parametric trigger model using the current weather and herd health array.
7. Phase 4 — Firebase Backend: Firestore Schema and Cloud Functions
The Firebase backend serves as the data layer between the Cloud Run API and the SvelteKit frontend. Firestore stores herd profiles, cached HMRI scores, backtest results, and portfolio configurations. Cloud Functions act as a caching proxy — checking Firestore before calling Cloud Run, keeping latency low and Cloud Run costs minimal for repeated queries.
7.1 Firestore Collections
| Collection | Document ID Pattern | Key Fields | Cache TTL |
|---|---|---|---|
herds | {county}_{species}_{seq} | county, lat, lon, species, avg_herd_size, insured_value_usd, biosecurity_tier | Permanent |
hmri_cache | {county}_{YYYY-MM-DD} | county, date, hmri, alert_level, heat_days_14d, precip_21d_mm | 24 hours |
backtest_results | {county}_{species}_{trigger}_{threshold}_{window} | trigger_frequency, expected_annual_payout_usd, notable_years | 7 days |
portfolios | {portfolio_id} | name, policies[], total_insured_value_usd, weighted_avg_hmri | Permanent |
alerts | Auto-ID | county, species, hmri, alert_level, fired_at, acknowledged | Permanent |
7.2 Cloud Functions: HMRI with 24-Hour Cache
exports.getHMRI = functions.https.onRequest(async (req, res) => {
res.set("Access-Control-Allow-Origin", "*");
const { county, lat, lon, species } = req.query;
const today = new Date().toISOString().split("T")[0];
const cacheKey = `${county}_${today}`;
// Check Firestore cache first
const cached = await db.collection("hmri_cache").doc(cacheKey).get();
if (cached.exists) {
return res.json({ ...cached.data(), source: "cache" });
}
// Cache miss — call Cloud Run
const response = await axios.get(
`${CLOUD_RUN_URL}/hmri?lat=${lat}&lon=${lon}` +
`&species=${encodeURIComponent(species)}`
);
const data = {
...response.data, county,
cachedAt: new Date(),
expiresAt: new Date(Date.now() + 24*60*60*1000)
};
await db.collection("hmri_cache").doc(cacheKey).set(data);
return res.json({ ...data, source: "live" });
});The caching architecture is critical for cost control. A single HMRI computation requires fetching weather data from Open-Meteo and running ONNX inference on Cloud Run. With 9 counties and potentially hundreds of daily users, uncached calls would generate significant Cloud Run costs. The 24-hour Firestore cache reduces Cloud Run invocations by approximately 95% at typical usage patterns.
7.3 Firestore Security Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /herds/{doc} { allow read: if true; allow write: if false; }
match /hmri_cache/{doc} { allow read: if true; allow write: if false; }
match /backtest_results/{doc} { allow read: if true; allow write: if false; }
match /{document=**} { allow write: if false; }
}
}All write operations are blocked from the client. Only Cloud Functions (which use the Firebase Admin SDK and bypass security rules) can write to Firestore. This prevents data tampering from the frontend.
8. Phase 5 — SvelteKit Frontend
The frontend is a SvelteKit application integrated into the existing cytos.dev Firebase Hosting site. It provides two primary interfaces: a live Herd Risk Map and a Parametric Trigger Designer.
8.1 Herd Risk Map
The risk map uses Leaflet.js to render circle markers for each of the nine monitored counties. Marker color reflects the current HMRI alert level, updated in real time by calling the getHMRI Firebase Function for each county on page load.
// HerdRiskMap.svelte — marker color update after HMRI load
const ALERT_COLOR = {
"Normal": "#22c55e",
"Watch": "#eab308",
"Advisory": "#f97316",
"Critical": "#dc2626",
};
async function loadAllHMRI() {
await Promise.all(Object.entries(HERD_DATA).map(async ([key, data]) => {
const res = await fetch(`${FUNCTIONS_BASE}/getHMRI?county=${key}` +
`&lat=${data.lat}&lon=${data.lon}` +
`&species=${encodeURIComponent(data.species)}`);
const json = await res.json();
markers[key].setStyle({
fillColor: ALERT_COLOR[json.alert_level] || "#22c55e",
fillOpacity: 0.85
});
}));
}Geospatial Risk Distribution (Macro Triage)
Metrics: Asset Location, Species, HMRI
Layout: Grid/Spatial
Geospatial Risk Distribution
Species: BEEF CATTLE
Herd Size: 850
Species: BEEF CATTLE
Herd Size: 1,200
Species: DAIRY CATTLE
Herd Size: 1,800
Species: HOGS
Herd Size: 5,000
Species: HOGS
Herd Size: 8,000
Species: BROILERS
Herd Size: 45,000
8.2 Parametric Trigger Designer
The Trigger Designer allows an underwriter or actuary to configure a parametric trigger — selecting a county, species, trigger type (heat, cold, drought, or composite), threshold value, and lookback window — and run a 20-year backtest against historical data. Results are displayed as a Chart.js bar chart showing annual trigger days, with triggered years highlighted in red.
// TriggerDesigner.svelte — backtest call
async function runBacktest() {
const herd = HERD_DATA[form.county];
const res = await fetch(`${FUNCTIONS_BASE}/runBacktest`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
county: form.county, lat: herd.lat, lon: herd.lon,
species: form.species, trigger_type: form.trigger_type,
threshold: Number(form.threshold),
window_days: Number(form.window_days),
start_year: form.start_year, end_year: form.end_year,
coverage_usd: Number(form.coverage_usd)
})
});
result = await res.json();
renderChart();
}The Trigger Designer is the most commercially significant component of the platform. It gives an underwriter the ability to answer the question that determines parametric product pricing: “If I set this trigger at this threshold, how often would it have fired over the past 20 years, and what would the expected annual payout have been?” That question cannot be answered without both the engineering infrastructure and the domain knowledge to interpret the answer.
Parametric Trigger Weights (Index Formulation)
Metrics: Heat, Cold, Drought, Pathogen
Constraint: 100% Total Allocation
Parametric Trigger Weights
Adjust the index formulation. Total must equal 100%.
---
9. Phase 6 — Deployment and Integration
9.1 SvelteKit Static Adapter
// svelte.config.js
import adapter from "@sveltejs/adapter-static";
export default {
kit: {
adapter: adapter({
pages: "build", assets: "build",
fallback: "index.html" // SPA fallback for client-side routing
})
}
};9.2 Firebase Hosting Configuration
{
"hosting": {
"public": "build",
"rewrites": [{ "source": "**", "destination": "/index.html" }],
"headers": [{
"source": "**/*.@(js|css)",
"headers": [{ "key": "Cache-Control", "value": "max-age=31536000" }]
}]
}
}9.3 Build and Deploy
npm run build
firebase deployThe entire platform — frontend, Cloud Functions, Firestore rules, and hosting configuration — deploys in a single command. This is a deliberate architectural choice: the deployment pipeline is simple enough that a domain expert can own it without a dedicated DevOps team.
10. The Domain Expert’s Irreplaceable Role
The technical architecture described in the preceding sections is reproducible by any competent cloud engineer given sufficient time and a requirements document. What is not reproducible — what cannot be specified in a requirements document — is the biological knowledge that makes every decision in this architecture correct.
10.1 The Cost of Getting the Biology Wrong
Consider three specific decisions in this platform and what happens if they are made by an IT developer without domain expertise:
Decision 1: The precipitation lookback window. An IT developer would use a 7-day rolling window — the default in most weather analytics libraries. The correct window for beef cattle body condition score decline is 21 days. A 7-day window would miss the slow-onset drought stress that drives the majority of beef cattle mortality events. The trigger would fire too late, after the damage is done, and the parametric product would fail to protect producers.
Decision 2: The THI threshold. An IT developer would find the most commonly cited THI threshold in the literature — 72 — and apply it uniformly across all cattle species. The correct application is species- and production-system-specific: THI 72 is the onset threshold for dairy cattle in milk production, but the economically significant threshold for beef cattle on pasture is closer to 78, because beef cattle have greater thermal tolerance than high-producing dairy cows. A uniform threshold would generate false positives for beef cattle and undercount heat stress events for dairy cattle.
Decision 3: The pathogen pressure proxy. An IT developer would model disease risk as a binary flag from USDA APHIS outbreak reports. The correct model uses evapotranspiration deficit and excess precipitation as proxies for the environmental conditions that favor pathogen proliferation — because the economically significant disease events in swine and poultry occur 2–4 weeks before a reportable outbreak, during the subclinical phase when immune suppression is building. A reactive model based on outbreak reports is useless for parametric insurance, which must trigger before the loss event, not after.
In each case, the error is not a coding error. It is a biological error. And in each case, the consequence is a mispriced insurance product.
11. Conclusion
AgroVar Sentinel is not a demonstration of coding ability. It is a demonstration of what becomes possible when deep domain expertise is combined with modern AI-assisted development tools.
The platform solves a real problem in the livestock insurance market: the absence of biologically grounded parametric risk products. It does so by encoding 29 years of veterinary and biomedical science into a production-grade cloud application — a data pipeline that fetches and processes 20 years of weather and livestock data, a machine learning model whose features and thresholds are derived from published veterinary science, a Cloud Run API that serves real-time risk scores and 20-year backtests, a Firebase backend with a domain-correct data schema, and a SvelteKit frontend that gives underwriters and producers the tools to design and evaluate parametric insurance triggers.
Every architectural decision in this platform — from the 21-day precipitation window to the species-specific HMRI weights to the Firestore cache TTL — reflects a biological or operational judgment that required domain expertise to make correctly. An IT developer could have built the infrastructure. Only a veterinary scientist could have built it right.
The role this platform demonstrates is not a one-time project contribution. It is a continuous, high-frequency function: calibrating models as climate shifts, onboarding new species and geographies, interpreting outbreak events, validating trigger frequency against loss records, and explaining biological risk to producers and regulators. That is a full-time role, and it is a role that does not currently exist at most insurance IT companies.
AgroVar demonstrates what that capability can produce when domain knowledge takes precedence.