Infrastructure migration in progress: some features are temporarily unavailable.
Senior Platform Engineer @ SemgrepAWS / EKSeBPF & CiliumDistributed SystemsOpenTelemetry ContributorK3S HomelabScotland, United KingdomSenior Platform Engineer @ SemgrepAWS / EKSeBPF & CiliumDistributed SystemsOpenTelemetry ContributorK3S HomelabScotland, United KingdomSenior Platform Engineer @ SemgrepAWS / EKSeBPF & CiliumDistributed SystemsOpenTelemetry ContributorK3S HomelabScotland, United Kingdom
01 Work Experience
Semgrep
Senior Platform Engineer
May 2025 – Present AWS / EKS / Kubernetes platform across 25 clusters for an AppSec SaaS serving large enterprise customers.
- Run scan execution on Argo Workflows at scale: long-lived, latency-critical workloads kept within the control plane's etcd and apiserver limits.
- Migrated the org's ingress off deprecated ingress-nginx to Envoy Gateway on the Kubernetes Gateway API, with Cilium as the eBPF CNI and Linkerd as the L7 mesh.
- Built per-customer infrastructure cost attribution: usage metered at the kernel with eBPF, reconciled to the AWS bill.
BenchSci
Senior Software Engineer / SSE2
Oct 2022 – May 2025 Pharma R&D SaaS. Three years building the infrastructure other engineers deployed on. Promoted to SSE2 within 12 months.
Event-Driven Data Platform
BenchSci turns 25M+ scientific papers into structured biomedical knowledge through NER, LLM extraction, and knowledge-graph linking. Document processing was a weekly batch with pipeline-granularity caching: data freshness capped what the product team could ship, and unchanged work was reprocessed every cycle.
- Rebuilt it event-driven on GKE: per-document events, per-document caching, scale-to-zero, so only changed documents reprocess. Processing went from weeks to minutes, cost dropped from $644 to $69 per 2.5M docs (−89%), and the platform scaled to 100K+ concurrent documents with the full 25M+ corpus reprocessable on demand.
- Made it the default: for the ML researchers using it, adoption was a decorator and a Python function. The framework owned deployment, event semantics, the message log, and live data testing. ~200 engineers adopted it as the data platform's foundation.
Also at BenchSci
- OpenTelemetry org-wide adoption: every team was rolling their own logs, metrics, and tracing. I drove a company-wide OTel rollout that gave every service all three by default. Incident time-to-identify dropped from 94 to 23 minutes (−75%) and false-alert volume fell 15%.
- GPU inference at cloud-quota limits: ran in-pod L4 inference for ~50 in-house ML models (paper extraction, entity enrichment, vision ML) inside the same event-driven pipeline, autoscaling across regions against a ~25K L4-GPU quota and bursting onto spot capacity when available. Each document's work stayed in one region to avoid cross-region transfer.
- Fixed the post-incident process: it was bespoke per team. I wrote the company RCA playbook and led a cross-functional squad through it. Time-to-resolution fell 40% and the recurring SLA violations stopped.
Ensono
Platform Engineering Consultant (contract)
May 2022 – Oct 2022 Greenfield GCP data platform for a hotel chain; Cloud Composer pipelines, IaC, BigQuery modeling.
Hometree
Senior Platform Engineer
Sep 2021 – May 2022 dbt / BigQuery modernization for a UK home-warranty business; ER model optimization; resilience work on a legacy platform.
AXA
Senior Platform Engineer
Jan 2021 – Sep 2021 Azure ETL + Terraform IaC; ML infrastructure that contributed to a 40% reduction in customer acquisition cost.
Led an on-prem to GCP migration; mentored junior engineers. Role eliminated in COVID restructuring.
Earlier Career
Chubb (2018–2020): account servicing for multinational corporate insurance; the final year was engineering: process automation, data science & analytics. Automated the majority of regional account-servicing admin and won two UK-wide hackathons, including an ML fraud classifier for claims handlers.
02 Personal Engineering Homelab
All of this runs on a bare-metal K3s cluster I operate at home, deployed with GitOps. Source: github.com/jomcgi/homelab.
- EmberVM, a Firecracker agent substrate (projects/embervm): a serverless invoke substrate on hardware-isolated Firecracker microVMs. A stateless node daemon restores a copy-on-write warm-base snapshot (28ms restore, ~140ms cold start to first model call) and reverse-proxies HTTP over vsock into the guest; workloads are declarative Helm values, and durable state lives outside the VM. The guest never holds a real secret: a TLS-terminating egress proxy swaps placeholder tokens for the real credential at the network hop, so sandboxed code uses a GitHub token it can never read or exfiltrate.
- Semgrep scans on agent diffs (projects/firecracker/semgrep): a snapshot-warm guest with a resident Semgrep engine scans the code the agents write, synchronously: ~22ms restore, ~0.72s for a full scan with taint analysis against a ~6.7s cold start, so the scanner sits inside the agent's write path instead of a CI queue.
- Grimoire (jomcgi.dev/app/grimoire): takes scanned tabletop sourcebook pages and turns them into a domain knowledge graph you can ask questions of. An LLM extraction pipeline (a hosted frontier model, or my own in-cluster Qwen) fills Postgres + pgvector with ~37k entities and ~48k relationships across 35 books, extracted off-pod as bounded, idempotent Argo CronWorkflows so nothing heavy touches the request path. On top: a per-campaign reader, an entity browser, and a rate-limited public RAG chat that cites the exact source chunks behind every answer. Access control is one visibility predicate every read path routes through, so the DM's secrets stay secret.
- Local inference & autonomous maintenance: llama.cpp serving Qwen3.8-27B on a single consumer RTX 4090 (4-bit GGUF weights, q8 KV-cache); an MCP gateway in front of a self-built MCP server; and scheduled Claude routines doing autonomous platform maintenance over a Postgres + pgvector knowledge graph.
- OCI Model Cache Operator (projects/operators/oci-model-cache): a Go operator that streams HuggingFace models into an OCI registry and rewrites pod volumes at admission, so pods mount models like container images. Sealed-interface state machines make invalid phase transitions a compile error.
- Platform plumbing: five custom Bazel rulesets, notably rules_helm, a rules_semgrep running the pinned scan engine directly for hermetic diff scans from 2 minutes to 30 seconds, and a WIP rules_ocaml making OCaml a first-class Bazel language; Argo CD GitOps; Envoy Gateway / Gateway API ingress behind a Cloudflare Tunnel (no open ports); Cilium (eBPF CNI, network policy, WireGuard), Kyverno, 1Password Operator, self-hosted SigNoz.
- loom (pre-alpha, with a collaborator, to be open-sourced): a take on Palantir Foundry, a typed-object data platform with built-in lineage and governance, on a Rust + DataFusion + DuckLake core. Postgres is the only stateful coordinator, so a new dataset, domain, or transform adds no new system to run.
03 Technical Expertise
Stack
AWS (EKS, S3)GCP (GKE, BigQuery, Pub/Sub)AzureKuberneteseBPFCiliumGateway APIArgo CDTerraformBazel
Data & Observability
SnowflakeSQLMeshdbtPostgres (PGvector/HNSW)Neo4jIcebergMetabaseOpenTelemetryPrometheusGrafanaSigNozHoneycomb
Languages & AI Infra
GoPythonRustTypeScriptSQLStarlarkFastAPISvelteKitFirecracker / microVMsvLLMMCPAgent orchestrationClaude Code