Projects¶
One evolution · three chapters
From services, to a template, to an agent platform¶
This is not a pile of projects — it is one line of work that compounds.
Three production ML services taught the lessons; a governed template
encoded them; and agent-local proves the same governance philosophy
generalizes to a new domain — local LLM agents. Each chapter is the
foundation of the next.
Why three repos, not one
Separate repositories with an explicit, bidirectional contract — not a
monorepo. Each has its own lifecycle, audience and release line; agent-local
reuses the template's IaC when it needs cloud, and the template documents it as
a sibling. Knowing where to draw that boundary is the point.
Chapter 1 · The ML-MLOps Portfolio¶
The portfolio is not three models — it is one production system that happens to serve three of them. Each service ships with its FastAPI contract, test suite, Docker image and Kubernetes manifests; around them sits the shared MLOps surface: Terraform-provisioned GKE and EKS clusters, Kustomize overlays per environment, GitHub Actions CI/CD with quality gates, MLflow tracking, Prometheus + Grafana monitoring, and the incident writeups that prove the system was operated, not just deployed.
395+ automated tests and 18 architecture decision records hold it together — every non-trivial choice is documented with the alternatives it rejected.
How to review it
Pick one service and follow its evidence chain: metrics → serving path → deployment → incident. The debugging deep dive on BankChurn is the strongest 10-minute read.

The three services inside the portfolio — each with its own deep-dive page. Hover to hold, drag to browse, or click a card to bring it to center:
churn classification
BankChurn Predictor¶
AUC 0.87 90% coverage FastAPI · K8s · SHAP
Cost-aware churn classification — and the serving incident that went from 81% errors to 0% at half the CPU.
financial nlp
NLPInsight Analyzer¶
80.6% accuracy 98% coverage CPU-only serving
Financial sentiment with an explainable, low-cost inference path — the heavier transformer documented as a rejected trade-off.
demand forecasting
ChicagoTaxi Pipeline¶
R² 0.96 6.3M rows PySpark · temporal CV
Demand forecasting at scale with strictly temporal validation — and the data leak that was caught before the metrics were published.
All the infrastructure, testing, security and monitoring proof behind the portfolio lives in one place:
Chapter 2 · The Production Template¶
The second project is what the first one taught: an open-source starter system that encodes the portfolio's production lessons as reusable defaults. Scaffold a new ML service and it arrives with the serving and training patterns, deployment overlays and operating guardrails already in place — the mistakes the portfolio paid for once, prevented by default.
Inside the box: a FastAPI serving scaffold with the single-worker + ThreadPoolExecutor pattern, training pipelines with quality gates (metric, fairness, leakage), 6 env×cloud Kustomize overlays for GCP and AWS, Terraform modules, CI/CD that signs images and attests SBOMs (SLSA L2), closed-loop drift monitoring, 38 documented anti-patterns and 43 ADRs.
Its differentiator is the governed AI-assisted development layer: behavior rules, skills, workflows and an audit trail that keep agentic coding reviewable and bounded — engineered, not hidden.
Why it matters
The portfolio proves I can build and operate ML services. The template proves I can turn that experience into a system other teams can adopt.
Chapter 3 · agent-local — the LLM plane¶
The third chapter takes the template's governance philosophy — AUTO / CONSULT
/ STOP, eval-gated autonomy, policy-as-data, no fine-tuning until a written
gate fires — and generalizes it to a new domain: local, multi-tier LLM
agents. The hard-won logic (grammar-constrained routing, an adaptive reasoning
loop, objective escalation, a deterministic policy gate) lives in a reusable
core/; a new domain is a thin usecases/<name>/ folder, never a fork.
The shipped example use-case is a WhatsApp store assistant — but the point is the platform, not the store. It is a sibling of the template, not a copy: it reuses the template's Terraform and Kustomize when it needs cloud, and runs the template's day-2 maintenance lanes on its local model tiers.
The signal
Chapters 1–2 show I can build and systematize ML. Chapter 3 shows the system composes — the same governance generalizes to a domain it was never written for. That is the jump from "builds things" to "designs platforms".
This is an active build. Rather than rewrite this page each week, the
status below tracks against the published plan
(ACTION_PLAN_LLM_AGENT.md)
— ✅ done · 🔨 in progress · ⏳ gated/next.
✅ Phase 0–1 · foundation
Runtime, router & policy gate¶
- ✅ llama.cpp bench + tier contract (E4B router gate 20/20)
- ✅ grammar-constrained routing with confidence
- ✅ reusable
core/+ thinusecases/(ADR-001) - ✅ deterministic policy gate; all tools read-only
✅ Phase 2 · controller & verifier
Governed execution¶
- ✅ ExecutiveController + per-tier circuit breaker
- ✅ policies as versioned YAML +
decision_id - ✅ cross-tier verifier + bounded self-consistency, reflection notes isolated from evidence (ADR-009)
- ✅ 11 evaluation sets (incl. adversarial injection) + offline gate
🔨 Phase 3 · observability
Telemetry & learning loop¶
- ✅ decision telemetry contract + PII redaction
- ✅ shadow sampling
- 🔨 retrieval growth loop (alias mining from logs)
- 🔨 golden set + replay against real traffic
⏳ Phase 4 · gated / next
Scale & adapt¶
- ⏳ SQLite queue + sagas (durable multi-day flows)
- ⏳ live WhatsApp webhook + cloud overflow path
- ⏳ comparative experiment vs portfolio datasets
- ⏳ QLoRA / DPO — only when the written gate fires