What we build
Four things.
All running.
Two you can open on somebody else's server tonight. Two run inside products, so you get the counts and the dates instead.
One codebase, three platforms.
Flutter on iOS, Android and web, localised from the first commit, released by script.
One Flutter codebase runs the same product on iOS, Android and web, so a change lands everywhere at once. The string catalogue existed before the first screen did, which is why the shipped app carries 29 languages across 35 locale files without a rewrite.
Certificates, provisioning and phased rollout are scripted lanes, 15 for iOS and 17 for Android. A fix is a tag, not an afternoon. The app behind that link is our own product, so you can install it and judge for yourself.
The database is the boundary.
Postgres enforces the rules, so there is no API tier to write, deploy, or be paged about.
The app talks to Postgres directly. Row-level security is the authorisation boundary. Scoring, referrals and settlement run as database functions, and a tampered client gets nowhere. One schema carries 25 tables, 51 functions and 48 policies.
It held. 32,252 registered players wrote 863,000 predictions through a tournament that ran from 11 June to 19 July 2026.
Edge functions on the second product run on Deno, in TypeScript, behind one audited handler shared across every route. That handler carries an allowlist, a method gate, token verification and rate limiting.
The container estate is public.
31 images, rebuilt daily since 2015, signed and scanned on every build.
31 public images ship across five repositories on GitHub. Every one is rebuilt daily by cron. Tags are CalVer dates and are never deleted, so an old pin still resolves to the image it named.
docker-base publishes five platforms from one build. The other four publish linux/amd64 only, which covers most of the machines they end up on.
The base image runs the full gate set on every build. That means Hadolint, container structure tests, an image scan, Cosign signing, an SBOM and a provenance attestation. Whatever runs traces back to the exact build that produced it.
Agents walk through the same door.
Seven tools behind OAuth 2.1, under the same row-level policies a person runs under.
An agent client connects to a Model Context Protocol server and calls the tools it exposes. Seven tools sit behind OAuth 2.1. The product owns its data and its rules; the client does the reasoning.
Agent calls mint a per-user token and run under the same row-level policies as a human session. A model gets no looser path, so an agent that misbehaves is stopped by the same policy that stops a tampered client.
That server sits behind OAuth, so you cannot open it and check it yourself. What you can open is the gate set. An agent-written change runs the same checks a human change runs, before the merge, and a failing check stops it.
What an agent pipeline sends to a model provider, and where the terms for it are settled, is on Trust.
Probably not a fit.
Three shapes we decline, and the one we take. Better to know now than in month two.
The shape it fits
- The product decision is made, and you can defend it upward.
- Somebody on your side can review a pull request and approve a merge.
- The infrastructure is yours, and access can be scoped and granted.
The shapes we turn down
- Discovery, where what to build is still open. That decision is yours.
- A fixed specification with a fixed date. We fix the period; the scope is decided inside it.
- Work where nobody on your side can approve a merge. You would be buying a dependency.
The term itself is three months, extendable once to six. How we work sets out what that includes, what it needs from you, and what you keep at the end.
One mail. No form.
Tell us what is in the way.
Say what you're building and where it stopped.
Copy it into your mail client if that is easier.
The draft opens with
- What you are building
- What is in the way
- The stack
- When you want to start
The contact page says who answers, and what the reply contains.
