The Platform
A self-hosted platform that runs a portfolio of AI-powered apps — and delivers changes to them. Designed solo, built spec-first with AI coding agents.


Problem
Shipping several small AI-powered products as one engineer means every app re-solves the same problems: AI provider access, cost control, deployment, monitoring, conventions. And LLM APIs bill by usage — one runaway loop in a hobby app can cost real money. The goal: run many small apps without rebuilding infrastructure each time, never let AI spend go unmetered — and get changes from idea to reviewed, running software without hand-carrying each one.
Solution
A personal platform of small single-purpose services — more than thirty repositories, each self-describing, all sharing one version-pinned contracts library and governed by a written log of over a hundred architecture decisions. Every AI call passes through one gateway that alone holds the provider keys, so cost control cannot be bypassed. Every repository is built by a coding agent from a written spec, and a human decides what ships: a change counts as done only when the owner has accepted it on a running review environment, never because an agent said so. Software about running AI, built with AI — in three layers below.
Features
- Runtime — one AI gateway holding all provider keys, with synchronous budget pre-flight checks and automatic downshift to a free local model near a ceiling
- Runtime — Claude subscription usage metered as its own provider, and per-call model and effort choice with separate metering per backend
- Runtime — live platform state streamed over server-sent events; a GPU job queue with VRAM-aware admission for local image and 3D generation
- Build plane — an agent runner dispatching coding-agent sessions: a subscription-authenticated Codex CLI by default, Claude Code selectable, local-model profiles, and a hosted provider only through the gateway
- Build plane — cross-repo coordination through a gated demand protocol; every repository adopts the same operational memory, with session files instead of hand-written handoffs and scheduled audits
- Build plane — a design studio: interview-first missions, design regimes, versioned design systems, binding owner rejection direction and a coverage gate
- Build plane — a documentation hexagon with a decision index, and a launcher that detects stale builds and rebuilds in one click
- Delivery plane — task-driven delivery: backlog issue, owner-approved plan, implementation pull request into the development branch only, required checks, a review environment, and owner acceptance before the issue resolves
- Delivery plane — parked work: an agent waiting on CI, a merge or an owner decision ends its run with a structured wait condition and is resumed by a new run instead of idling
- Delivery plane — a SonarQube quality gate enforced as a required merge check on the development branch (pilot app), local code measurement, and an AI backlog planner with a preview-then-confirm gate
- Delivery plane — a ship-clean rule (apps born by the platform carry no platform traces) and a console with a native task-delivery view
Architecture
- Owner intent — Harvest · registry · backlog
- Factory — task delivery (plan → PR → checks → review)
- Demand coordinator
- Agent runner — coding agents
- Apps
- AI gateway — sole key holder
- Budget pre-flight · usage over Kafka
- Live state feed → console
Tech
- Java
- Spring Boot
- Angular
- Python
- Kafka
- PostgreSQL
- Docker Compose
- Server-Sent Events
- Hexagonal architecture
- AI coding agents
- Claude Code
- Codex
- Local LLMs
- SonarQube
Challenges
- Making cost enforcement impossible to bypass rather than merely discouraged — solved structurally: only the gateway holds provider keys, so there is no path around metering.
- Keeping dozens of small repositories consistent as a solo engineer — solved with a conventions library, repo templates and a compliance validator.
- Evolving shared contracts across many consumers without breakage — solved by publishing them as a pinned, versioned package.
- Coordinating changes that cross repository boundaries when every agent works inside exactly one repo — solved with the demand protocol: requests are files, dispatch is a service, approval is human.
- Trusting work done by agents — solved by keeping the facts separate: agent exit, tests, checks, review environment and owner acceptance are recorded independently, and none of them alone marks an outcome complete.
- Not paying for agents to wait — solved by parking: a run that needs CI or a decision ends with a structured wait and a new run picks up from there.
Lessons
- Boundaries enforced by structure beat boundaries enforced by discipline: a rule the filesystem enforces cannot rot.
- Spec-first, agent-built development works when the spec is the source of truth and a human holds the review gate.
- Metering belongs at the choke point, not in every app.
- "Done" is a claim, not a verdict — the evidence has to come from something other than the thing that did the work.
- Retire machinery that stopped earning its keep: the earlier mission-style workflow and the app studio are parked in favour of simpler task-driven delivery.
Future work
- Run the platform hosted rather than local-first — its first product, Planotell, is already live in production
- Bring more apps from idea to repository through Harvest, the registry, backlog and task delivery
- A richer live visualization of platform state