Build to Think: A Mid-Year Audit
The year-to-date audit, through the lens of Build to Think — the eighteenth edition since March, regenerated with /audit on Fable and Opus 5, this one 2026-09-03. One ink, one accent, short on purpose.
A cooking coach for a new dad went from git init to a deployed, phone-first app in 28 hours. A war-game engine went from nothing to 48,249 lines in four days — three genres on one substrate, no map data, no keys, and a README that publishes its own calibration misses. That fortnight is the year in miniature: 1,176 commits before work and after dinner around a day job at Google, nineteen products anyone can open in a browser, no servers to babysit and almost nothing to log into.
Nine minutes after the engine committed its third mode, its author opened a second repo and rebuilt the same game from scratch with the opposite thesis. That repo holds 7,472 lines, a passing test suite, a built bundle — and, when this audit’s sweep reached it, not one commit. Sixteen minutes later it had a commit and a remote. Last edition’s headline debt, an architecture deployed from a branch GitHub had never seen, was cleared within 48 hours; the essay published two days later said so: the loop works on its author. Then the same shape came back, bigger, in a directory the audit didn’t know existed until this morning’s ls — and closed itself before the report was written.
Lesson 1 — Projects die between sessions, not during them
Nothing here died of a hard problem. Things died of the cold start — sitting back down and not knowing where you left off. Every project that matured left itself a note; every one that stalled, stalled in the gap. The evidence is uncomfortably literal: one version’s final commit reads fix: resolve 27+ TypeScript build errors; another died finished, on branches nobody pushed.
This round’s exhibit is the purest since February. The rival battle-royale repo is a complete product — seven test files, a calibration CLI, a duel runner — and for sixteen minutes this morning it existed on one laptop’s filesystem and nowhere else. Then it got a commit and a remote, while this paragraph was being drafted — the right outcome, closed by hand, in the same gap everything else in this section died in. The habit tracker’s rebuild carries the same risk in slow motion: its July privacy fix, the one that moved a personal supplement list out of the shipped bundle, has been sitting uncommitted for five weeks. The handoff note in the golf record still says a DNS record is “still pending” seventeen days after that domain went live; the note’s header still reads “State as of Aug 17” with thirty-five commits underneath it. The append-only log next to it grew to forty entries and stayed true.
The uncomfortable half of the finding is about the tooling. In July a small harness was built against exactly this — a ship-state table, a campfire command, a morning brief. The prompt history since the last edition shows zero invocations of any of them. Of 219 prompts typed in that window, 44 are variants of push — a fifth, the same fifth the Aug 19 essay measured across ten months. What worked was the report: a person read that production ran on an unpushed branch, and pushed. What didn’t work was the on-demand layer, because on-demand means remembering. The counter-exhibit is the new engine’s own note: dated, versioned, golden seeds, the exact command to rerun each calibration, and a line recording that “a parallel session owns the STORY tab.” Written the same day the code was.
The living log · how a project survives the gap
The transfer: give every project one living file — part lesson log, part spec: decisions with reasons, what’s next, what changed your mind. Then split it: let the machine write the part that’s a fact (branch, last push, what’s live) every time you stop, and keep the human’s hand for intent. A team that records why it chose something stops relitigating the choice; a team whose status line writes itself stops lying about it by accident.
Lesson 2 — Everything you build wants to become a game
Look at where each exploration ended up: an atlas of San Francisco became a drivable city. A launch-planning idea became a deckbuilder. Golf-course data became a sim you can lose at. A friend’s life became an RPG; even the habit tracker is a rat you keep alive. The AI underneath is indifferent. The pull toward play comes from the person: a general capability has no handles, and giving it rules, feedback and stakes is how a mind gets a grip on it.
This round it happened three times in five days, on one engine. The engine was built genre-agnostic first — architecture tests ban Math.random, Date.now, and every house or place name from the core — and then grew a mode a day: a single-elimination bracket on Santa Catalina Island with fog of war as a per-side belief state (“~80–120 when the truth is 240”); a desert battlefield “where water is the clock,” carried entirely by data; a 48-house Bay Area theater with 2,256 directed opinions, one for every ordered pair; a 32-champion battle royale. The direction of the drift is the finding: each mode is less playable than the last. The theater’s design goal is “the player watches, reruns, and studies; nobody drives.” The rival repo goes further — “the product is the data… not the story.” The game became an instrument, the way the golf record did in July, and the instrument reports its own misses: a matchup landing at 45% against a 53.5% target, a champion who “dies early too often for the spec’s taste.” Canon is allowed to lose; the goldens lock determinism, never who wins.
The refusals are as telling as the drift. The cooking coach has every ingredient of a game — twenty ordered dinners, skills that accumulate, scaffolding that fades — and declines the loop on purpose: its difficulty setting is “a complexity setting, not a judgment,” and its stated end state is not needing it anymore. An app engineered to lose its user.
The transfer: when an idea isn’t landing — a pricing model, a roadmap — build a toy version people can lose at. Losing teaches faster than reading. Then make the toy publish where it’s wrong: a game that prints its own calibration table is a model, and a model is something a team can argue with instead of about.
Lesson 3 — Build the memory first, then chisel the product out of the rest
Building to think works like sculpture: early versions pile up material — code, dead ends, notes — and the product is what’s left after you cut the rest away. The cutting is only safe if the design lives somewhere outside the code. That’s why the memory comes first.
The Dopamine Rat proves it. Built four times; dependencies per version ran 2 → 7 → 10 → 3. The version that shipped is the smallest, and the only one that started from a written record of what the first three got wrong. Doppler applied the rule on day one instead of attempt four: two dependencies, no backend, and 264 CI data invariants. If a number can be derived, derive it; anything hand-set is labeled as opinion.
Four repos subtracted this round. The golf record committed the fixture before the parser — “the fixture the parser will be written against” — then spent a weekend deleting: five copies of one reader became one, five pipelines became one composition, and a single commit of +32 / −1,115 removed two whole pages, including last edition’s centerpiece, folding them into one. The site got smaller as the record got bigger. The flagship retired its April essay without deleting it: nav link gone, an archive notice pointing at the map that replaced it, sitemap priority cut. It kept its URL and lost its authority. The site published a profile of its author as a roast and then cut the roast out in six commits until only a five-step method remained. And the cooking coach’s reckoning commit — “Make the kitchen mechanics rise to the writing” — took a postpartum recipe set from 25 down to “the ten that truly reheat or eat one-handed” and named the seam: “the content is the product, and the tooling around the 5:30pm moment was the weak seam.” The engine wrote its memory as an event log — every decision carrying the alternatives it rejected — and treats its three screens as three reads of one recording. Its README has a section titled Deliberate V1 cuts.
One repo, three homes · the July extraction
Maturity as separation of concerns you can survive: give each exploration its own address, and keep — don't destroy — what it grew out of.
Lesson 4 — AI compressed implementation. It did not compress judgment
The cold start is how projects die; whether the thing deserved to exist is why you never come back. bass is the year’s honest failure: ten commits of supply for a demand that never existed — one practice ever logged. The code was fine. The decision was wrong, and every added feature compounded it. Rat v3 made the same mistake with more ceremony — Garmin OAuth before daily use was proven — and died finished. film died in a day, zero photos.
This round’s evidence is a run of decisions about what a machine is allowed to decide. The golf record’s new watch adapter takes the device’s measurements and refuses its model — “every Garmin-computed number is refused at the adapter… so every number the site prints is derivable and explainable” — and rejects even a labeled exception, because “one labeled exception becomes the precedent for the next.” Its round-matching runs under a stated policy — “proposed by machine, confirmed by hand… reruns preserve those verbatim” — and the loader reads only what a person confirmed: “a proposed link is a guess, and a guessed join is invented data.” Per-shot GPS is committed to a public repo by signed decision, with a revisit if clause for the day a private-residence course appears. The market map published its own strongest refutation and corrected the entry about the author’s own product in the direction of accuracy. The golf sim’s newest course has no boundary on the map, so it ships a flagged hull with its retirement written in. And the engine’s rival attaches a confidence and a citation to every rating, and is willing to write “No direct evidence.”
The open call is the fork itself. Two implementations of one game, chronicle-first against analytics-first, built hours apart by the same person, is a design disagreement settled by building both — Build to Think at its most literal. But the argument lives in two READMEs; the engine has no decision log at all; and nothing says which side wins.
The transfer: when you automate a judgment, keep a human signature on the join, and store it where re-running the machine can’t erase it. The tool should never both set the goal and grade it. And when two of you disagree about a design, building both is a legitimate review — as long as the losing side gets written down, because the side that isn’t written down is the side that doesn’t get committed.
The stack — whatever you don’t have to log into wins
The monthly infrastructure bill is $0 — but the money is the least of it. Sort the portfolio by what each project depends on and a pattern falls out: everything that survived runs on things you can hit without logging in — OpenStreetMap, MapLibre, git, localStorage, a static host’s free tier — and everything that rotted, rotted at an auth boundary: an OAuth flow, an expiring token, a service key. Not because open tools are better, but because they’re still there at 5am, on a phone, from a golf course. The path of least friction wins, and a login screen is friction.
Keyless → still running
- OSM + Overpass — two golf projects' course geometry; cost: an attribution line
- MapLibre — real maps, no API key
- Open-Meteo — live microclimates for the atlas’s weather-chase mode; no key
- git + a CDN — doppler's whole "backend"; scoring is a commit
- localStorage — the rat's database; the cooking coach's whole state; the flagship's job queue
- Jekyll + GitHub Pages — twelve years; its one death is opposite →
- a browser extension riding your own session — the watch's data, captured verbatim, no OAuth; the 2021 death across the aisle, solved by not asking
- hand-placed terrain — 48,000 lines of war game on zero external data; every ridge typed in
- Demucs, local — stems: no cloud, no accounts, no uploads; the price: only a demo lives at a URL
Auth-walled → where things rotted
- Garmin OAuth — built before daily use was proven; rat v3 died finished
- a Supabase anon key — five months of public writes on the flagship
- Universal Analytics — the site's one death in twelve years
- cron secrets & DNS aliases — the rat simplified; the failures moved here
- a stale Overpass mirror — the one that answers looks healthy; three courses baked from May data. The guard written after it caught a second mirror lying 50 days deep, in a different repo, on its first run
- a hosting team's URL — the war game's deploys answer a login screen; only an alias nobody wrote down is public, and the obvious address belongs to someone else
Tournament weekend was the field test. Thursday, July 23: git init at 3pm, a live tournament site by 11:31pm. Then every update, all weekend, came from a phone between rounds — 22 commits of scorecards entered hole by hole from the course in Ontario. Nothing on the board was ever set by hand: standings, odds and the champion badge all derive from the committed scorecards. No admin panel, no login. That’s the bar — run it from a golf course, on a phone, between shots — and any OAuth screen in that path kills the live board by Saturday.
The thesis has a control arm: a fresh problem went to a different agent — OpenAI Codex — and came back as a golf-course digital twin, which on day two added a Supabase tier with logins, the stack’s first new keys in months. Four editions later the pattern is data: its auth tier has gone untouched for five weeks, and its API surface answers 404 from outside. Nothing rotted loudly. Auth-walled things don’t; they just stop being checkable.
But keyless is not the same as trustworthy — the free endpoint that asks nothing of you can still hand you two-month-old data with a straight face — and it is not the same as findable either. Two of this round’s products are live on a free tier with no login in their path and no URL in their README, and the address a reader would guess for one of them is a stranger’s consultancy. Open beats auth-walled on survival; it buys you neither correctness nor a front door.
The transfer: count the credentials before you count the features — every key is a place the project can die while you’re not looking. Then go back and ask each keyless source how you’d know if it started lying. The ones that ask nothing of you also promise nothing to you.
What building on top found
Seven courses went into the golf sim in one evening. That meant leaning on parts of the pipeline nobody had leaned on, and three things fell out — each of them shipping silently since the day it was written.
- The parser had been dropping data. OpenStreetMap describes a shape as either a single way or a multi-part relation. The code asked for both, then skipped every relation. The query looked healthy; it returned rows. Torrey Pines South had been shipping with zero fairways.
- The map mirrors had been serving months-old data. The primary endpoint was rate-limited, the script failed over exactly as designed, and the backup answered with a June 1 snapshot. Nothing in the response said so. Three of eighteen courses baked from stale data in one run.
- Five messages had never once appeared on screen.
SPLASH,OUT OF BOUNDS,CLONK,BEACHED,ON IN n— set, then overwritten in the same tick by the line after. Found only because the new character needed the same channel to speak through.
The sequel landed in a repo that didn’t exist when those bugs were found: the staleness guard, ported into the course map, refused a mirror serving 50-day-old data on its first run. And this round the pipeline met a course with no boundary at all — nothing in OpenStreetMap says where it ends — so the guard’s cousin shipped: a flagged interpolation with its own expiry written in. That’s the difference between a lesson learned and a lesson installed: one lives in your head, the other fires in a repo you haven’t started yet.
The transfer: when you inherit a pipeline you didn’t write, don’t audit it — extend it. Tests check the paths you thought of; the next feature walks into the ones you didn’t, and it’s free, because you were going to build it anyway. The same trick works on a system you inherited at work: the fastest audit of code nobody remembers is the next thing somebody needs from it.
The year in one line
The shape of the year · commits per week, in three acts
Two quiet months, a detonation, then a tail that keeps building: the spring is now, for the first time, only half the year — 50.7% of commits — with July and August the third and fourth months. The window had a shape of its own: a 34-commit Wednesday (the flagship’s whole market map in two hours and eight minutes before work), a weekend of golf-record subtraction, five silent days, then the two new products at the portfolio’s standard hours — four nights past ten, mornings before nine, one full daylight Monday for the coach. The mid-May flatline is Google I/O; the June trough is the move, New York to San Francisco. The clock hasn’t moved since it tipped last edition: 9pm leads 5am by three. And the census moved while being taken, for the fourth edition straight — this time a whole repo: the rival battle royale was uncommitted at the sweep, committed and pushed sixteen minutes later, and the engine redeployed in between.
The portfolio
This round’s deltas — Westeros War Games · bittman · MACKENZIE · bookmarks · MUNI golf · the site
Shipped & steady — The Doppler XII · archetypes · SF · Flow Slays IO · inference · stems · Level Atlas · Minecraft mods · course renderer · kareemrpg · prompts-mcp
Bench & footnotes — SF Rush · the Dopamine Rat · bass · the bench

Westeros War Games · catalina
A deterministic war-game engine that grew a genre a day: a 32-house bracket on Santa Catalina Island, a desert where water is the clock, a 48-house Bay Area theater where "nobody drives," and a battle royale. Every decision ships with its rejected alternatives and their scores. No map data, no keys — every ridge is hand-placed TypeScript — and the README publishes its own calibration misses. Nine minutes after the royale landed, a rival implementation began in a second repo — committed sixteen minutes after this audit found it bare.

bittman
A cooking coach for one cook — a new dad — built from git init to a deployed, phone-first app in 28 hours. Twenty ordered dinners, each teaching one technique; Dinner 20 has no recipe, only questions. Dad Mode is "a complexity setting, not a judgment." Its stated end state is not needing it anymore, and its last commit is a field report from the first real cook: "tacos confirmed as the core, hashbrowns demoted, salt math fixed."
MACKENZIE
Last round it merged its two products and forgot to push; this round it pushed within 48 hours and then closed the loop: a second capture extension (the watch), machine-proposed round links a human must confirm — "a proposed link is a guess, and a guessed join is invented data" — a goals engine that proposes a week and waits for a signature, and one command, pnpm refresh, that turns any new capture into a rewritten record. Then it deleted two pages. The site got smaller as the record got bigger.

Prompts · the flagship
X bookmarks → a curated gen-media prompt dataset, and now a public market map: 74 companies, a Momentum 25, and a 352-finding validation trail written in two hours before work. Its strongest refutation is published in its own audit; contested numbers stay contested; the entry about the author’s own product was corrected toward accuracy, not flattery. The April essay it replaced kept its URL and lost its authority.

The Doppler XII
Built in one evening, operated from the tournament, sealed by Sunday. Live scoring was literally git: commit a scorecard, the field’s phones update. Two runtime dependencies, no backend, 264 data invariants in CI. After the seal came “The 36th”: the playoff hole resurveyed from OpenStreetMap, shot by shot, with witness corrections amending the record.

SF Rush
Don’t read the commit count — the game was built across sf’s spring sprints, then copied out whole on Jul 12: 18k lines, six vehicles, real LiDAR terrain. The chart shows the full lineage; its default level is the Harbor Links golf course.

Flow Slays IO
A Slay-the-Spire deckbuilder about shipping a GenMedia model. The truest mechanic: the PM classes cannot deal damage — the whole kit is leverage on other people’s cards. July’s retheme added pixel-art combat and an honest balance simulator.

Archetypes
v1 was built entirely on a phone. v2 rebuilt the problem statement: 87 archetypes, 170 graded mappings, every objection attacked on schedule and the survivors published.

Course renderer
A golf-course digital twin on MapLibre + OpenStreetMap — refuses to invent geometry the map doesn’t know. The keyless thesis’s control arm: its auth tier has now sat untouched for five weeks — not broken, just no longer checkable from outside.

Stems
A local-first Demucs stem splitter whose demo renders music videos in your browser — ten styles, four generative sketches drawn from a hand-written FFT — and then, in twenty-three minutes, became a working Winamp. Its own note says the next step is to ship it outward.

Level Atlas
An atlas of level design in which the repo is the database: every entry a JSON file checked at build time, so a dangling reference fails the build instead of the page. Day two it built a space-graph engine instead of per-level artwork.

The SF atlas
An atlas built to answer a real question: where in SF to live. Its weather-chase mode colors 189 neighborhoods by live sun, wind, and warmth. It also grew a driving game, then gave it up: −19,963 lines in six reversible minutes.

LabsCraft v2 · minecraft-mods
An LLM-driven NPC mod deleted and rebuilt in ~100 minutes by 7 parallel agents — safe because the design was extracted into a spec first. A third mod, SportsCraft, golf inside Minecraft, is still in PR, honest that no one has run it.

Inference
Gen-AI unit economics, cited and interactive. Its 34-commit launch day exposed the missing source of truth; the fix made July’s refresh one commit instead of thirty.

MICKEY’S MUNIS · golf
A 16-bit sim on real course geometry — 360 holes, from Augusta to a Toronto par 3, still two runtime dependencies. Course 21 is the first with no boundary on the map at all: a flagged convex hull with its retirement written in — “if someone maps the real boundary, the path goes unused” — baked and merged by a cloud agent.

The site
The workshop’s logbook — and this audit’s publisher. This round it published a report on how its author builds — a fifth of all prompts are the word push — then spent six commits cutting the jokes out until only the method remained.
The Dopamine Rat
Dependency count per version: 2 → 7 → 10 → 3. v4 wins by deleting the other three. Its July privacy fix has been sitting uncommitted for five weeks — the campfire is lit; nobody has pushed it into git.

kareemrpg
A friend’s life as a walkable RPG. The tutorial folder quietly became the product — bias toward extending what works.
prompts-mcp
Learned MCP by implementing all four primitives and both transports over his own dataset. The bugs were the curriculum.
The bench
westeros-battle-royale: 7,472 lines and a passing test suite that spent sixteen minutes with no commit and no remote — the newest cold-start near-miss in the set. film died in a day with zero photos; two repos never reached a first commit.
The cadence
The bimodal builder · commits by hour of day (Pacific)
Every day of 2026 · Daily commits, week by week
Hover any day for its count and which repos moved. The dense block is the March–April detonation; the warm cell is the single busiest day (Apr 12, the inference launch).
The verdict
The portfolio isn’t a list of products; it’s a thinking log with a URL for each thought. This round the practice got mature enough to argue with itself in code. Two implementations of one game, built hours apart — chronicle-first against analytics-first, fifty bare ratings against twenty cited ones — are a design review conducted by construction. That is the whole method at its most literal. It is also the oldest failure in this file wearing a new coat: the losing side of an argument that was never written down is the side that doesn’t get committed.
The counterweight is the harness. Last edition’s debt was cleared in two days because a person read a report; the tools built in July to make that automatic have never been run. A report works when someone is looking. A hook works when no one is. Everything this round says about continuity points the same way: move the work off the command line and into the things that fire on their own, and let the machine write the status so the human only has to write the intent.
What none of this has been tested on is still other people — and the gap narrowed by exactly one simulation. The Bay Area theater is 48 autonomous houses holding 2,256 private opinions of each other, negotiating and betraying their way to hegemony while nobody drives. It is the closest this portfolio has come to modeling a room full of people, and every one of them is code. The golf record’s engine proposes, human commits is a two-party protocol with one party. The market map’s way of disagreeing — name the missing evidence, make it a watch item — has only ever been used against its own author. Whether any of it survives a second person with commit rights is the question a solo portfolio cannot answer, and the year has four months left to try.
Build to think; then commit what you built, because a repo with no first commit isn’t a project yet — it’s a very large scratch file.
Eighteenth dated edition since 2026-03-29. Census through 2026-09-03. Regenerated with /audit on Fable and Opus 5 across the run — this one on Fable. The long-form master report lives at ~/CodeProj/PROJECT_AUDIT.md.
