About
Self-taught developer. I started with vibe coding — describing what I wanted, accepting what the AI gave me, shipping it. It worked, right up until it did not. When something broke I had no idea why, because I had never really understood what I built.
Vibe coding is a legitimate starting point. It lowers the barrier to building real things, and that matters. But there is a ceiling. The moment something breaks in a way that matters — a race condition in a voting system, a silent data integrity bug, a security hole in an API you thought was fine — you need to understand what you built. If you do not, you are stuck.
I hit that ceiling. Instead of giving up on AI tooling, I changed how I used it. The difference is not whether AI writes the code. The difference is whether you understand it well enough to own it when things go wrong.
That shift — from accepting the first response to refusing to stop until you genuinely understand the result — is what Directed Output is about.
AI Art Arena is a live production voting platform built entirely through the Directed Output process. Every architectural decision — the atomic vote RPC, the three-client Supabase setup, the sliding-window rate limiter, the admin dashboard — is documented in the build log as it was made. The dead ends are in there too.
See the platform →I built a live AI art voting platform in public — 33 migrations, one atomic RPC, and a methodology for working with AI that actually holds up
A production Next.js + Supabase voting platform, built entirely in public with every decision documented. Here is what that actually looked like — the architecture, the bugs that got shipped, the things that only broke under concurrency, and what Directed Output means in practice.
The day I stopped fixing bugs and started fixing systems
Every link on my profile page was broken. After an afternoon of chasing URLs, I understood why — and instead of patching the links, I built a tool that makes this class of bug impossible to miss. That is the difference.
Why I replaced 5 database queries with one atomic Supabase function
Five sequential database queries in a vote handler create race conditions and ~200ms latency. One atomic PostgreSQL function eliminates both. Here is the exact problem, the fix, and what the refinement loop looked like getting there.
How I enforced rate limits in Next.js without ever storing an IP address
Storing raw IP addresses is a GDPR liability. Hashing them one-way with a secret salt gives you everything you need for rate limiting with none of the exposure. Here is the exact implementation — and why the salt can never change after launch.
If you are building something with AI tools and want it done with the kind of intention that holds up when things go wrong — that is the work I do. Get in touch.