Blog
Writing about software engineering, architecture decisions, and lessons learned
Production RAG: Three Retrieval Strategies and When Each One Wins
The RAG demo takes a weekend. Then retrieval silently misses, the model answers anyway — fluently wrong — and nobody files a bug because the answer reads right. Three retrieval strategies, from single-shot vector search to agentic loops, and the trade-offs that decide which one you need.
Running an AI Software Factory: Agents That Ship Production Code
How we restructured development at Navero so AI agents implement, verify, and review tickets end to end — with humans holding only the gates that matter.
Prompt Engineering Without Guesswork: Evals, Naive Prompts, and Reliable JSON
Most teams write prompts by vibes: tweak, run once, ship, break in production. Here is the scientific loop instead, with real eval scores, the mistakes everyone makes, which model tier fits which job, and the prefill plus stop sequence trick for JSON that always parses.
Local-First and CRDTs: From Naive Sockets to a Scalable Collaborative Editor
Why broadcasting keystrokes over Socket.IO falls apart, how OT and CRDTs keep documents converging, what local-first buys your UX, and how we built Cynoia's collaborative editor with Yjs, Lexical, IndexedDB persistence, and Socket.IO scaled through the Redis adapter.
End-to-End Testing LLM Features Without Calling an LLM
How we run full-stack Playwright suites over AI generation flows with zero API keys, zero cost, and zero flakiness — by swapping every model for a deterministic in-process fake.
Taming LLM Variance: Ensemble Scoring with Outlier Rejection
The same CV got a different score on every run. We fixed it with parallel ensemble scoring, statistical outlier rejection, and an eval that told us exactly how many attempts to pay for.
Never Lose an Interview: Resilient Video Uploads from the Browser
Candidates record proctored video interviews on flaky laptops and flakier Wi-Fi. Here is the IndexedDB + Web Worker + resumable-upload pipeline that stopped us from losing recordings.
Building a Proctored Test Runner as an Explicit State Machine
Camera checks, fullscreen enforcement, anti-cheat, and screen recording — coordinated by a typed lifecycle state machine instead of a tangle of React effects.
Event-Driven Video Processing on GCP: Killing the Request That Could Never Finish
Transcription takes 2–5 minutes; load balancers give up long before that. Why the synchronous version of Navero's video screening pipeline was structurally doomed, and how GCS events, Cloud Functions, and async webhooks replaced it — with the costs stated honestly.
Why Your Cron Jobs Run Three Times: Zookeeper Leader Election for Horizontally Scaled Node.js
The moment you run a second instance, every scheduled job runs twice — and a scheduled broadcast reaches real users twice. How we solved it in Hexabot (open-source chatbot, 700+ stars) with Zookeeper leader election, after the naive fixes failed.
Real-Time Collaboration: The Editing Is the Easy Part
CRDTs solve concurrent editing — a library import solves it for you. What nobody warns you about is everything around it: permissions enforced at the socket, presence, offline recovery, and network partitions. Field notes from building Cynoia's collaborative editor.