Skip to content

Projects

A few things I have designed and built, and what each one decided. Where a project is not finished, or was stopped on purpose, it says so.

A governed AI engineering system

Multi-agent development under written rules, with a pipeline that ships pull requests on its own.

Designer and builder2026 – PresentIn production on my own codebase

Seven specialized AI roles, a written set of conventions they must follow, and an autonomous pipeline in CI that turns a labeled issue into a reviewed pull request. It was built to let one engineer sustain a codebase that would normally occupy a small team.

One labeled issue, from trigger to pull request. Blue stages are AI, purple are deterministic checks, and pink is where I am asked for a decision.

One labeled issue, from trigger to pull request. Blue stages are AI, purple are deterministic checks, and pink is where I am asked for a decision.

The problem

Working alone, there is no second pair of eyes. With AI assistance the bottleneck moves: producing code stops being the hard part, and keeping it consistent, reviewed and explainable becomes it. Unsupervised assistants drift from the conventions of the codebase, re-solve problems that already have an answer, and leave decisions undocumented.

I treated that as an architecture problem rather than a prompting problem. The answer was a system with roles, contracts and gates, in which the AI is the workforce and the governance is mine.

What I built

  • Seven specialized roles, each with a written contract and a briefing pack: an architect that plans and never edits code, an implementer that executes a locked plan and surfaces every deviation before acting, a reviewer that returns an explicit verdict, plus project-manager, product-owner, guideline-architect and issue-editor roles.
  • Guidelines for them to work under: per-layer and cross-cutting convention documents, each split into its rationale, its rules with stable identifiers, its open backlog and its change log. Amendments go through a formal request-for-changes process, and structural decisions are recorded as Architecture Decision Records.
  • An autonomous factory in CI: labeling an issue triggers a GitHub Actions workflow that runs architect, implementer, reviewer and a fix loop inside an isolated git worktree. Stages exchange schema-validated JSON, deterministic gates check types, lint and schema conformance, and when the pipeline is unsure it escalates by commenting on the issue, then resumes from my answer. The output is a pull request I review.

What the evaluation showed

The factory was evaluated against its own run history rather than against impressions. In that first window, every one of the 54 pull requests it opened was merged, and none was reverted. About 40% of runs failed, and reading the traces showed that almost none of those failures came from the model: they were orchestration defects, including a cache permission change on the platform that silently broke resumption, and the absence of a clean exit for runs that correctly concluded there was nothing to do. Both went into a hardening iteration.

The same discipline decided where not to use AI. Asked whether the agents needed retrieval-augmented generation over the codebase, I measured the corpus, wrote the decision record, and adopted embeddings for one narrow job — finding conceptually duplicate issues — while rejecting a vector database outright at this scale. Code is better served by exact search, and a hand-written rule index beats a probabilistic one when every claim has to be citable.

Why it matters beyond my own project

Every mechanism in it has a human equivalent: a definition of done, a review gate, an architecture decision record, a convention that changes only through a documented proposal. That is the point. The system was shaped for one product, and applying it elsewhere means redoing the discovery and rewriting the conventions for that codebase, not copying files. What transfers is the method, and the judgment about which parts of an engineering process should never be delegated.

  • Claude Code
  • GitHub Actions
  • Multi-Agent Workflows
  • Context Engineering
  • JSON Schema
  • Python
  • Bash
  • Architecture Decision Records

A social travel mobile app

A cross-platform product designed, built and operated end to end by one engineer.

Solution Architect and Full-Stack EngineerDecember 2024 – PresentRelease candidate, approaching closed beta on Android

A consumer mobile application in the travel space, from scoping documents and a proof of concept through to a release candidate: domain model, database, backend services, mobile client, test suite and delivery pipeline. The product is not named here until its legal groundwork is finished.

Architecture

A React Native and Expo client in TypeScript over a Supabase backend, roughly 730 source modules and 70,000 lines, organized in explicit layers: domain logic, services, a server-state layer, hooks, and components. Each layer has a convention document that states what it may depend on, which is what keeps a codebase this size navigable when one person carries all of it.

The database holds 44 tables with the constraints, functions and triggers that enforce the rules the client must not be trusted with. Messaging is realtime, and the interface is internationalized from the data layer up rather than translated afterwards.

The decision that shaped it

The proof of concept ran on Firebase and Firestore. It worked, and I moved off it anyway. Two things decided it: the pricing model charges per read and the document model encouraged fetching more than each screen needed, which together made a near-zero-cost launch implausible at any real user count; and the domain had turned out to be strongly relational, with travelers, trips, destinations, preferences and relationships all cross-referencing each other.

Migrating early, while the cost of moving was measured in weeks rather than quarters, was the cheapest version of that decision. The schema was redesigned around a generic publication model, where a trip is one kind of publication, so that other content types can be added without reshaping what already exists.

Quality and delivery

  • 6,746 automated tests across 370 suites, with about 96% statement coverage, gated per path under a policy that a threshold may be raised but never lowered to make a red run green.
  • Pre-commit hooks and a two-job pipeline that separates lint and typecheck from tests, so a green lint never disguises a red suite.
  • Over 140 merged pull requests and more than 530 closed issues, tracked in GitHub Projects against a milestone-gated launch roadmap.
  • Structural choices recorded as Architecture Decision Records, including the one above, and large refactors run as numbered waves that each leave the application shippable.
  • TypeScript
  • React Native
  • Expo
  • Supabase
  • PostgreSQL
  • React Query
  • Jest
  • GitHub Actions
  • i18next

The contact path behind this site

A small backend whose job is to keep an email address off the page.

Architect and developer2025Live, running this site's contact form

The form on this site posts to a route handler on Vercel, which calls an API gateway on Google Cloud that holds the API key and enforces the rate limit, which in turn calls a Cloud Run service that checks the request origin, verifies the captcha, validates attachments and sends the message. Rate limiting sits at the gateway because both the serverless function and the container are short-lived, so an in-process counter would protect nothing. The address itself is never printed in the page.

  • Google Cloud
  • API Gateway
  • Cloud Run
  • Python
  • Next.js
  • reCAPTCHA

AI quiz platform

A generative-AI product that was stopped on purpose.

Architect and developerDecember 2023 – December 2024Paused

A platform that generated quizzes with a large language model on Google Cloud: containerized services aimed at Cloud Run, a relational store for the generated content, a document store for user data and metrics, and a React Native client. I paused it on an architectural finding rather than on lost interest. Keeping generated questions genuinely varied needed semantic comparison, which means sentence embeddings and somewhere to put them, and that dependency broke the near-zero-cost model the project was built around. Topics that are ambiguous across languages were a second unsolved problem.

  • Google Cloud
  • Vertex AI
  • Cloud Run
  • Cloud SQL
  • Firestore
  • Docker
  • React Native
  • Python

Simulation experiments

Two small Python projects, built to think with.

Personal projects2025 – 2026Personal experiments

A physics sandbox that simulates forces on spherical bodies, with the forces supplied as configuration so different combinations can be compared in the same scene. And an ant-colony simulation that separates the environment from the decision model, so that rule trees, belief-desire-intention agents and swarm behavior can be run against identical scenarios - foraging, territorial conflict, maze solving - and watched side by side.

  • Python
  • Simulation
  • Agent Models
  • Data Visualization