All work
Some details omitted — NDA. Architecture and outcomes only, no client data.
Innover's clients needed large, realistic relational datasets to test and demo their systems on — without touching real customer data. Before this platform, that meant hand-rolled scripts per client: brittle, slow to adapt to a new schema, and easy to get wrong.
Designed a full-stack React + FastAPI platform for synthetic data generation, including an LLM-based generation mode (OpenAI SDK, guardrails, preset templates) producing schema-validated sample rows.
Integrated five SDV models (CTGAN, TVAE, GaussianCopula, CopulaGAN, HMASynthesizer) and a PII masking engine (spaCy NER + Faker) for secure, constraint-preserving relational synthesis.
Built tabbed previews, post-generation dashboards, and export pipelines, cutting dataset-exploration setup time 30%.
Optimized metadata inference and constraint-handling pipelines, cutting runtime 25–40%. Internship extended three months on the strength of it.
25–40%
pipeline runtime cut
Metadata inference and constraint-handling pipelines, measured across benchmark runs.
0%
faster dataset-exploration setup
Tabbed previews, post-generation dashboards, and export pipelines.
0 mo
internship extended
Extended on the strength of the metadata inference work.
Most social apps optimize for one thing: attention, measured in public likes and follower counts. Aura Farmer started from a different question — what replaces that feedback loop if you take away the vanity metric it's built on? Built for Voodoo's Studio incubator, competing against 14 other teams for a spot to keep building.
Integrated RESTful Supabase APIs for real-time post, comment, and media handling in React Native profile and vault interfaces.
Optimized Supabase queries, cutting redundant API calls by 40% and reducing profile fetch time from 2.0s to 1.5s.
Ran an agile, SCRUM-based development cycle to plan sprints and coordinate across roles.
Recognized as 1 of 3 finalists from 15 teams in Voodoo’s Studio incubator.
3 / 15
incubator finalist
Top 3 of 15 teams, Voodoo's Studio incubator.
0%
fewer redundant API calls
Supabase query optimization.
2.0s → 1.5s
faster profile fetch time
Same optimization pass, measured in testing.
I use Spark at work without ever seeing what's underneath the DataFrame API — the scheduler, the shuffle, the part where a map/reduce job actually becomes threads doing work. So I built MiniSpark: a small version of it myself, in C, with Resilient Distributed Datasets and a DAG scheduler, to find out.
Built RDDs supporting map, filter, join, and partitionBy, with lineage recomputation recovering lost partitions at under 5% overhead.
Architected a DAG scheduler using POSIX threads and a worker pool, accelerating throughput 4× on datasets up to 10GB in multicore environments.
Implemented thread-safe queues, mutexes, and custom memory allocators — eliminating race conditions and cutting memory fragmentation 20%.
0×
throughput on multicore
DAG scheduler over a POSIX thread pool, datasets up to 10GB.
<5%
overhead recovering lost partitions
RDD lineage recomputation.
0%
less memory fragmentation
Custom allocators, thread-safe queues and mutexes.
Every terminal session runs through a shell without most people thinking about what it's actually doing between a command being typed and a process running. I wanted to know, so I built WSH in C — parsing, fork/exec, piping, and background jobs, from scratch, with both interactive and batch modes.
Authored a Unix-like shell from scratch with interactive and batch modes — fork/exec, 128-argument parsing, environment variables, built-in commands, piping, and background jobs.
Covered over 80% of daily Bash functionality.
Verified reliability running 500+ diverse commands, including nested pipelines and background jobs — zero memory leaks under Valgrind, execution speed within 5% of Bash.
0%+
of daily Bash functionality covered
fork/exec, piping, background jobs, built-ins.
Zero
memory leaks under Valgrind
500+ commands tested, including nested pipelines.
Within 5%
of Bash execution speed
On standard workloads.
Thales needed a working animal adoption platform — browsing, filtering, and an adoption workflow that had to hold up on everything from a shared office desktop to a phone on a slow connection.
Built a full-stack animal adoption platform (HTML, CSS, JavaScript) with interactive filtering and secure adoption workflows across responsive, cross-device layouts.
Architected modular components and optimized client-side rendering with efficient DOM updates, cutting page load times 25%.
Integrated and validated backend routes for data exchange, applying Thales' engineering standards for secure, fault-tolerant deployment.
25%
faster page loads
From optimizing client-side rendering through modular components.
Context
I wanted the site itself to be the strongest proof of the "full-stack engineer" claim on the résumé — not a wrapper around the other five projects, but a sixth one, built with the same care and the same willingness to explain a decision instead of just shipping it.
The problem
A personal site usually rots the moment it ships: a new project means editing five different files, a color change means hunting through components, and "add a case study" means writing a new page from scratch. I wanted adding a project to mean touching exactly two files — one data entry, one prose file — with everything else (routes, sitemap, OG images, cross-links) derived automatically.
Decision
Structured data + Zod validation as the only source of truth
Alternatives considered — a headless CMS; MDX frontmatter carrying the structured fields directly
A CMS is real infrastructure to run for a single-author site. MDX frontmatter for structured fields was the original plan, but it means duplicating facts — a project's year or stack living in two places that can quietly disagree. Keeping every factual field in typed, Zod-validated TypeScript data files and reserving MDX for prose only means there's exactly one place each fact can live, and a malformed entry fails the build instead of shipping broken.
Decision
Generative covers instead of placeholder images
Alternatives considered — stock photography; blank/gray placeholder boxes; screenshots mocked up after the fact
There are no real screenshots yet — the repos this site is proud of are still being published. Faking screenshots would be dishonest; leaving gray boxes would look unfinished. A deterministic, seeded point-field per project reads as a deliberate sleeve system instead of a gap, and swaps for a real image later with zero template changes.
Decision
One WebGL scene, not WebGL throughout
Alternatives considered — a persistent GL layer across every route; no WebGL at all
"Immersive" and "loads in under 1.5 seconds" pull against each other. The resolution is to spend the GPU budget in exactly one place — the homepage hero — deferred behind a static poster and loaded after first paint, rather than spreading a smaller GL budget thin across every page.
What I'd do differently
I'd write the Zod schemas before writing any component, not just before writing the data — I ended up tightening a few schema constraints (referential integrity between projects and skills, mainly) after the fact, once I'd already hit the gaps by hand.