Generated 2026-06-07, viewed through the bent lens of Build to Think.

“No design doc could have described this project, because the project didn’t exist until I started building it.”

A confession, up top: the author is a PM on Google Flow who ships more side projects in a quarter than many engineering teams ship in a year, refuses to write design docs, and then writes a document called a “Project Audit” about the projects he refused to design. For four audits the side projects ran parallel to the day job. This is the one where they walked up and shook its hand. In the nine days since the last audit, two net-new efforts appeared — both pointed straight at Flow. One rebuilt the product as a playable game: a roguelike deckbuilder where your deck is the team and the enemies are what breaks your build. The other is a share-ready intelligence brief on Flow’s own launch — a 132-post reception study, built with a Copy-to-Google-Doc button and the named execs deliberately stripped so it travels. No design doc preceded either. They cost $0 to host and took the evenings a full-time job doesn’t claim. The building is the thinking — and this quarter, the thinking was about Flow.

Audit Meta — the audit, audited

PARALLEL AGENTS 4 the delta livedin three repos DAYS SINCE LAST AUDIT 9 the heartbeatreturned PERMISSION PROMPTS 0 by policy — seesettings.local.json COMMITS INSPECTED 1,084 across 20 repos,3 locations

Every audit wants to measure itself. This one obliges — and notes that the highest-signal round yet was also one of the smallest by raw commit count. In nine days the portfolio produced a playable game of the day-job product (flowtcg) and a circulate-ready intelligence brief on the day-job launch (bookmarks). The audit is downstream of the building, and this time the building aimed home.

Metric Value
Repositories crawled 20 (across ~/CodeProj, ~/ummerr.github.io, /tmp/archetypes-audit) — one new since last round (flowtcg)
Shipped to production 11
Total tracked commits ~1,084 (+43 since May 29; StreakUp excluded)
Infrastructure cost $0 (Vercel Hobby, GitHub Pages, Supabase Free, itch.io, OpenStreetMap, USGS 3DEP)
Prior audits in the lineage 5 — Apr 12, Apr 16, Apr 18, May 29, Jun 7 (this one)
Engineers employed on this portfolio 1 (not by training)

The year at a glance

Zoom out from the nine-day delta to the twelve-month backdrop. Most of it is empty. The live cells cluster in the right-hand third — the “2026 run” — with the tallest cells at the very rightmost edge.

Cumulative commits — rolling 52 weeks · Jun 2025 → Jun 2026

JunJulAugSepOctNovDecJanFebMarAprMay0366732cumulative commitsApr 12 · +84Mar 26 · +55

The same year as a running total. Flat through summer and fall, then the line tilts up hard in late winter and never quite settles — the labelled dots are the two steepest single days. The line draws itself left-to-right as it scrolls into view; the endpoint is today.

Daily commits — rolling 52 weeks · Jun 2025 → Jun 2026

JunJulAugSepOctNovDecJanFebMarAprMayMWF2025-06-01: 0 commits2025-06-02: 0 commits2025-06-03: 0 commits2025-06-04: 0 commits2025-06-05: 0 commits2025-06-06: 0 commits2025-06-07: 0 commits2025-06-08: 0 commits2025-06-09: 0 commits2025-06-10: 0 commits2025-06-11: 0 commits2025-06-12: 0 commits2025-06-13: 0 commits2025-06-14: 0 commits2025-06-15: 0 commits2025-06-16: 0 commits2025-06-17: 0 commits2025-06-18: 0 commits2025-06-19: 0 commits2025-06-20: 0 commits2025-06-21: 0 commits2025-06-22: 0 commits2025-06-23: 0 commits2025-06-24: 0 commits2025-06-25: 1 commits2025-06-26: 0 commits2025-06-27: 0 commits2025-06-28: 0 commits2025-06-29: 0 commits2025-06-30: 0 commits2025-07-01: 0 commits2025-07-02: 0 commits2025-07-03: 0 commits2025-07-04: 0 commits2025-07-05: 0 commits2025-07-06: 0 commits2025-07-07: 0 commits2025-07-08: 0 commits2025-07-09: 0 commits2025-07-10: 0 commits2025-07-11: 0 commits2025-07-12: 0 commits2025-07-13: 0 commits2025-07-14: 0 commits2025-07-15: 0 commits2025-07-16: 0 commits2025-07-17: 0 commits2025-07-18: 0 commits2025-07-19: 0 commits2025-07-20: 0 commits2025-07-21: 0 commits2025-07-22: 0 commits2025-07-23: 0 commits2025-07-24: 0 commits2025-07-25: 0 commits2025-07-26: 0 commits2025-07-27: 0 commits2025-07-28: 0 commits2025-07-29: 0 commits2025-07-30: 0 commits2025-07-31: 0 commits2025-08-01: 0 commits2025-08-02: 0 commits2025-08-03: 0 commits2025-08-04: 0 commits2025-08-05: 0 commits2025-08-06: 0 commits2025-08-07: 0 commits2025-08-08: 0 commits2025-08-09: 1 commits2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 3 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 2 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 1 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 4 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 1 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 1 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 3 commits2026-02-16: 1 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 2 commits2026-03-01: 2 commits2026-03-02: 1 commits2026-03-03: 2 commits2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 6 commits2026-03-08: 11 commits2026-03-09: 27 commits2026-03-10: 11 commits2026-03-11: 0 commits2026-03-12: 15 commits2026-03-13: 19 commits2026-03-14: 18 commits2026-03-15: 2 commits2026-03-16: 0 commits2026-03-17: 3 commits2026-03-18: 2 commits2026-03-19: 0 commits2026-03-20: 3 commits2026-03-21: 6 commits2026-03-22: 0 commits2026-03-23: 5 commits2026-03-24: 2 commits2026-03-25: 14 commits2026-03-26: 55 commits2026-03-27: 32 commits2026-03-28: 22 commits2026-03-29: 12 commits2026-03-30: 9 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 3 commits2026-04-04: 5 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 2 commits2026-04-10: 0 commits2026-04-11: 13 commits2026-04-12: 84 commits2026-04-13: 17 commits2026-04-14: 35 commits2026-04-15: 5 commits2026-04-16: 21 commits2026-04-17: 16 commits2026-04-18: 35 commits2026-04-19: 4 commits2026-04-20: 29 commits2026-04-21: 0 commits2026-04-22: 24 commits2026-04-23: 2 commits2026-04-24: 8 commits2026-04-25: 5 commits2026-04-26: 6 commits2026-04-27: 2 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 1 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 1 commits2026-05-08: 2 commits2026-05-09: 2 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 4 commits2026-05-27: 48 commits2026-05-28: 12 commits2026-05-29: 7 commits2026-05-30: 8 commits2026-05-31: 0 commits2026-06-01: 1 commits2026-06-02: 2 commits2026-06-03: 22 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 4 commitslessmore

Eleven months of quiet, then the 2026 run — the GitHub-style heatmap renders the shape of the portfolio on a single row. The brightest cell is Apr 12 (the day inference shipped). The second-brightest is May 27 — `sf`'s arcade-mechanics explosion, 43 commits in that repo alone. The cluster on the far-right edge is the move to San Francisco: six weeks of terrain pipelines, biometric crons, and a drivable LiDAR city. Grayscale by default — density is the signal — with a single spot of warmth on the busiest day. Hover any cell for the date, its commit count, and the repos behind it; the week and weekday light up so you can place it.


What changed since May 29

The day job stopped being a backdrop and became the subject. The top-level list grew by one — flowtcg, born Jun 2 — and it is Flow: Ascent, a roguelike deckbuilder set inside the Flow render pipeline (more below). Meanwhile bookmarks shipped a share-ready Flow + Omni exec brief at /flow-brief and grew the Omni reception corpus to 132 posts; sf kept polishing The Rush into a cinematic arcade circuit; and golf became a playable 3-hole prototype. Everything else (gravityDopeRat, archetypes, bass, inference, minecraft-mods) sat stable — shipped, and waiting.

Lifetime commits per project

commitstotalummerr.github.io364bookmarks276archetypes160sf114inference63gravityDopeRat35bass10minecraft-mods9archetypes-audit8golf5flowtcg3dopeRatGravity2film1testExport1

Every repo the author owns, ranked by lifetime commits — regenerated live each audit. ummerr.github.io (11+ years) and bookmarks (the flagship) still lead, but the new bar this round is sf: 105 commits in 41 days, already the fourth-largest column in the portfolio. golf, its terrain-pipeline sibling, sits near the bottom — born small, on purpose. Strict grayscale; the cloned-reference StreakUp is excluded.

The new throughline is the day job, made literal. Last round’s throughline was terrain — teaching himself a geospatial graphics pipeline twice. This round, the two highest-signal builds don’t run parallel to the day job; they are the day job, rebuilt in the only language this author fully trusts: a working artifact. flowtcg renders the product as a game you play. bookmarks/flow-brief renders its launch as evidence you can act on. A PM’s most engaged form of thinking about a product turns out to be building one beside it.


The day’s hours, plotted as a clock

Midnight retook the top slot by a hair: 00:00 (109 commits) edged 11pm (106) and 8am (106), with 10pm (85), 9pm (78) and noon (77) close behind. The pattern is still resolutely bimodal — a late-night building wing and a morning sprint — and the shape is the whole point. This is work that happens around a full-time job, in the hours the job doesn’t claim. Nobody schedules a game engine for 11pm; it schedules itself.

Commits by hour of day — 24-hour radial

00 06 12 18 24h commit clock

The warm spokes — midnight, 11pm, 8am, 9–10pm, noon — anchor the bimodal day. This round midnight is back on top by a hair, the late-night build edging the morning sprint. The 4–6am wedge is still the only stretch the keyboard rests.


The portfolio, project by project

Jump to any deep-dive below. Bold marks what changed since the last audit.

This round’s deltasFlow: Ascent — the product, rebuilt as a game · bookmarks — the Flow + Omni exec brief · sf — The Rush · golf

Shipped & steadyDopamine Rat (v1 → v3) · Archetypes · inference · bass · minecraft-mods · kareemrpg · the site

Bench & footnotesVidMetaPrompt · smaller projects · the Build-to-Think scorecard


The New Headline: Flow: Ascent → flowtcg

Status: Playable • Commits: 3 • Born: Jun 2, 2026 • Print-pipeline → game in: two commits Stack: Next.js 15 · React 19 · Zustand · Zod · Tailwind v4 · Vitest (33 tests)

“This repo began as a card design & print pipeline. It is now a playable game.” — the README, narrating its own pivot.

A PM who works on Google Flow built a single-player roguelike deckbuilder — Slay the Spire’s exact core loop — and set it inside the Flow render pipeline. It is the most on-the-nose, and most revealing, object in the entire portfolio.

The deck is the org. Cards come in curated families that map onto how software actually gets shipped. Engineers are team members — Junior Engineer, rules text “Ships small, ships often,” evolving into Senior Engineer — whose attack becomes damage and block becomes block. Prompts are the curated offensive plays (the creative act, weaponized). Infrastructure is the curated defense (the thing that keeps you alive). You climb a branching map — ⚔️ Fight, 👹 Elite, 🔥 Rest, 🧠 Boss — HP carrying between fights, drafting 1-of-3 rewards, reading each enemy’s telegraphed intent, managing energy and statuses (Vulnerable, Weak, Frail, Strength, Poison). The enemies, per the README, are “what breaks your build.”

It’s engineered like a product, not a toy. The engine (lib/game/) is a pure, framework-agnostic, deterministic (state, action) => state reducer with randomness threaded through a seeded RNG (FNV-1a + mulberry32), so a whole run is reproducible and testable headless. Coverage is real: 33 unit tests across combat, run-loop, and content — including a winnable.test.ts that proves the game is actually beatable — plus a pnpm validate linter that checks every deck, enemy, and map resolves.

Build to Think verdict. The fastest way to know whether a PM understands a product is to watch what they build unprompted when they’re trying to enjoy themselves. He built his own team’s loop — ship small, ship often, fight what breaks the build — into something with energy, statuses, a boss, and a win state. That’s a product model, expressed as play. No design doc could have produced it; only the building could.


The Ongoing Headline: sf → sf.ummerr.com

Status: Shipped • Commits: 118 (+13) • Sprint: 50 days, Apr 19 – Jun 7, 2026 (committed to today) Stack: Astro 5 · React 19 (islands) · Three.js 0.184 · Rapier (WASM physics) · r3f + drei + postprocessing · MapLibre GL · @turf/turf · Tailwind v4 · TypeScript · pnpm Live: sf.ummerr.com

The single most active repository in the portfolio, and it began the day after the last audit. Its README is one line: “a personal log of my move to San Francisco — the prep, the lore, and everything in between.” What grew from that line is two apps sharing one repo and one obsession with SF’s actual topology.

/ — the atlas. A hand-drawn paper-and-ink map of San Francisco on MapLibre (no Mapbox token; OpenStreetMap data, free tier). DEM topography with hillshade and contours. Personal waypoints layered on top: the apartment (drawn as a blueberry), family, Equinox gyms, Google offices, and toggleable layers for cafes, bars, burritos, groceries, golf courses, parks, microclimate, and isochrones. Query-param “weather mode” and “golf mode” declutter the basemap. It is a relocation processed as a GIS project — the way to learn a city is to draw it.

/rush — the driving game. A full 3D arcade racer in the lineage of SF Rush 2049, built as a single Astro client:only React island so Rapier’s WASM and Three.js never touch the server. The basemap’s LiDAR elevation becomes a heightfield collider you actually drive on. The feature list is absurd for one person: a garage of five vehicles (car, motorcycle, city bus, a Waymo robotaxi, a pickup), each with its own physics tuning; a damage model that crumples panels and dents roofs on the visible car body; skid ribbons, sparks, a boost meter that drains and recharges; collectible coins; stunt scoring with airtime combos and flip recovery; bloom/vignette/DOF post-FX; a topographic minimap with district warp buttons; and synthesized audio. Today (May 29) a pluggable MapDef system landed a second playable world — the Googleplex / Mountain View campus, with a spiral garage, a food truck, a volleyball net, and knockable trees.

Commit choreography. 118 commits in 50 days, still committing today. After the May 27 arcade-mechanics explosion, this round was a polish sprint on The Rush: a cinematic dusk pass (AgX grade, IBL, lit windows, sunset bay, AO), N64-style dithered ground (tiled biome textures, Bayer dither, texel wobble), mega-ramps and banked curves carved by exaggerating the real DEM into launchable hills, and a “The Rush” time-trial circuit. A tuning.ts exposes 80+ live-editable knobs (via Leva in dev); every data class lives in its own *-data.ts so structure and logic stay separate.

Build to Think verdict. This is the thesis at full volume. There is no spec for “process a cross-country move” — there’s only the act of redrawing the city until it’s yours, then driving through it until it’s fun. The atlas is the author learning where he now lives; the racer is the author learning what it feels like to move through it. Both are the same LiDAR data, read two ways. No design doc gets you from “I moved” to “a destructible Waymo you can drive off a Mountain View ramp.” Only building does.


The Sibling: golf

Status: In development (local-only) • Commits: 8 (+2) • Sprint: May 7 – Jun 3, 2026 Stack: pnpm monorepo · Next.js 16 + React 19 + Tailwind v4 + Supabase (web) · Vite 6 + Three.js + lil-gui (sim) · Python: rasterio, numpy, shapely, geopandas (DEM pipeline)

sf’s quieter sibling, born from the same terrain obsession. A personal golf journal that renders the courses you’ve played as interactive 3D terrain, generated from public LiDAR elevation models — plus an embedded Three.js simulator scaffold to eventually play those courses on the same data.

Three structural layers: a Python pipeline (ingest.py) that pulls DEM tiles from USGS 3DEP (no auth), reprojects with rasterio, masks course polygons from OSM, detects feet-vs-meters units, and emits elevation.json + hillshade.png; a Next.js web app (home grid, /courses/[slug] 3D viewer with a 1–6× exaggeration slider, /rounds/new logging form, /sim/[slug]/[hole] iframe wrapper); and a Vite sim at phase-0 (a rotating cube that postMessages readiness to the parent — physics scaffolded, not built). A 244-line DECISIONS.md records the reasoning: why raw Three.js over r3f, why an iframe for the sim, why base: '/sim-app/'. Three courses are defined (Bethpage Black, Tobacco Road, Edgewood Tahoe), rendered today from synthetic DEMs while the real-source path is wired but untested.

Build to Think verdict. The loop is explicit in the product: play a course → log the round → study its real terrain in 3D → eventually play it in the sim. This round it crossed from pipeline into game — a playable 3-hole prototype (phases A–D) with overhauled swing mechanics landed on top of the terrain. Same learning ladder as sf (it even shares Three.js 0.184), but pointed at a hobby instead of a city. Two projects, one pipeline — discovered by building the first and reusing it for the second.


The Flagship: bookmarks → prompts.ummerr.com

Status: Shipped • Commits: 276 (+20) • Sprint: 96 days, Feb 28 – Jun 3, 2026 Stack: Next.js 16 · React 19 · TypeScript · Tailwind v4 · Supabase Postgres · Claude Haiku (triage) + Sonnet (depth) · marked (new)

Still the flagship, and this round it did something a PM org would normally staff a team to do: measured the reception of its own launch, rigorously, and packaged it to travel.

The Flow + Omni exec brief (new). A share-ready reception snapshot at /flow-brief, framed as Launch → Reaction → Landing, opening with a TL;DR positive/negative split and backing every point with an exemplar quote and a source-thread link. It surfaces the uncomfortable findings honestly — a dedicated section on safety filters overfiring (over-restriction complaints), a clustered Verbatims section of two-dozen-plus quotes, and first-hand June Reddit data folded into the table. It ships with a “Copy-as-Markdown” button (“Paste straight into a Google Doc, Slack, or email”) and named-exec references deliberately removed so it circulates without blast radius. The rest of the site is password-gated; this brief was built to be handed up.

The Omni Report, rev. 7. The underlying corpus grew to 132 posts (from 98), scored day-by-day across Reddit + tweets + open web: 66% positive / 8% negative, peaking at 72% positive on launch+4. The research instrument now runs a press desk on the day job’s own launch.

The Omni Report (new, unlisted). A build-time-rendered editorial page at /omni-report analyzing the open-web reception of Google’s Gemini Omni / Omni Flash video model. A curated 98-tweet corpus (rev. 6, grown from 79) across nine source clusters plus a Reddit deep-dive of ~140 threads. The data tells a story of a narrative flip: the launch-day verdict was “worse than Seedance”; within days the framing pivoted to “fundamentally a video editor, not a generator — Nano Banana for video.” Server-rendered SVG sparklines, numbered executive-summary cards, sentiment-by-day tables with inline %-bars (66.3% positive, +57 net), noindex‘d and absent from the nav. It is the first time the site tracks a specific competitor’s launch rather than the field in aggregate — the research instrument grew a press desk.

Dataset slicing (new). Four derived sub-datasets — T2I, R2I, T2V, R2V (text/reference × image/video) — each at /dataset/[slice] with its own stats and independent JSONL/CSV/JSON downloads, backed by SQL predicates over prompt_category and requires_reference. A shared lib/datasetSchema.ts centralizes the 27-field canonical schema so master and slices can’t drift; old ?slice=-less download URLs still resolve to the master set.

Research export (new). A ?variant=research flag strips PII (tweet_text, author handle/name, media_urls) while retaining tweet_id for rehydration — GDPR- and ToS-compliant academic sharing, exposed as a radio toggle in the download modal.

The access-gate detour (added, then removed). Apr 23–25 saw a client-side password gate, then a fake-404 overlay shown on every page load. Both were stripped by May 27 (Remove fake-404 gate overlay from site). The site is fully open again — a small, public, reverted experiment, the flagship’s signature move.

Everything load-bearing still loads. Two-tier classifier (Haiku triage, Sonnet depth), Chrome extension (Manifest V3), Image-to-Prompt reverse tool, quality audit, dataset datacard, methodology page, State of Prompting essay — all live, all free-tier.

Build to Think verdict. A mature project keeps discovering surfaces it couldn’t have specified. “A Chrome extension for bookmarks” became a dataset became an editorial became a competitive-intelligence desk with compliance affordances. The Omni Report is what it looks like when the day job (a PM on Flow, an AI video product) and the side project finally touch: the side project now reports on the competition, in public, for free.


The Long-Running One: ummerr.github.io

Status: Shipped (continuously, since 2014) • Commits: 366 • Lifespan: 11.6 years Stack: Jekyll • GitHub Pages • Bulma + custom CSS + Tailwind v4 • Geist + Instrument Serif

The heartbeat of the portfolio. Every other project ships through or alongside this site. 11 published essays, 10 portfolio case studies (Amex, Tradesy, Breazy, Kollider, Level, TheKind, Battle Bakery), a film photography gallery, a split-pane markdown editor with localStorage auto-save, and a 57MB Godot WebAssembly game embedded because at some point it became easier to embed it than not.

Tuesday is still the giant — 81 commits, 43% of all weekday activity. Noon peak. The daytime counterweight: the site is the writing project, everything else is the building project.

This round: the last commit before this audit was the previous audit (Regenerate project audit 2026-04-18). For six weeks the heartbeat held that note — the site is the publication layer for its own telemetry, and the telemetry paused while the author packed. The audit you are reading will land here as the next commit, breaking the silence.


The Trilogy: The Dopamine Rat (v1 → v2 → v3)

A habit tracker starring an emotional pixel rat. Three versions trace a philosophy pivot from gamification to harm reduction — and this round, v3 (gravityDopeRat) grew a nervous system. Across six deployed phases (Apr 26 – May 8), the tracker that once only knew what you told it learned to read what your body did: a Hevy auto-pull every four hours (strength workouts log themselves as auto-strength), a Garmin cron (10am + 9pm ET, pulling HRV / body battery / resting heart rate), and a vitality-compute engine (Sleep 0–40 + Recovery 0–30 + Training 0–30, with mismatch flags) that rewires the rat’s emotional state to biometrics. Then a cull: manual fitness and sleep-duration scoring removed, the dashboard recomposed, a Zustand persist migration (v3→v4) adding an overrides slice. 42 commits now, up from 26.

The trilogy — a philosophy by subtraction

V1 · FEB 2026 codexDopeRat ~700 activities · 0 commits "grind for points" Lab Rat → Free Rat V2 · FEB–MAR 2026 dopeRatGravity 38 components · 2 commits "every tool that fits" Claude API + WebLLM + Supabase V3 · MAR–MAY 2026 gravityDopeRat 42 commits · +sensor layer "measured recovery" Garmin + Hevy · vitality scoring · cron pulls

v1 named the problem. v2 tried every tool that sounded relevant. v3 asked what actually helps someone recover? — cut everything that didn't, and then, this round, learned to measure what's left: Garmin HRV, body battery, Hevy lifts, a subjective sleep tap, reconciled into one vitality score. The pivot from grind for points to measured recovery could not have been written down in February. It had to be built, used, and re-built.

The v3 mechanics underneath the new sensor layer: a 5-mood × 6-emotional-state × trajectory engine; blended scoring; urge surfing with a 20-minute timer and tiered partial credit; parent mode; harm-reduction physics (edible above spliff; alcohol escalates at drink 3+); offline-first with an async Supabase sync queue. Deployed on Vercel Node functions with three cron schedules (heartbeat, Hevy pull, Garmin pull). You could not have specified “reconcile a Garmin body-battery reading against a subjective sleep tap and a Hevy lift log” in February, because in February the product didn’t yet know it was a recovery instrument. It learned that by being used.


The Experiment, Doubled: Archetypes (v1 + v2)

Two audits ago this was a “single-commit experiment.” Last audit it was a “mobile-iconography endgame.” This audit it reached feature-completeness — and then stopped. The +44 commits since Apr 18 shipped the one surface that was still missing: a full Quiz + Reading assessment flow. Then silence since Apr 23. The project finished, and the author’s attention moved to a moving truck.

Archetypes — breadth → depth

V1 · BREADTH 10 systems × 3 interfaces vanilla JS · 5-day mobile sprint · 13 commits across 5 branches Jng Enn MBT Tar WZd CZd Grk Hin Nrs Kbl Compare Constellation Swipe "Can I map every system on a phone?" Built entirely on the Claude Code mobile app. V2 · DEPTH 6 systems × 37 routes Next.js + Three.js + Framer · desktop sprint · 163 commits KWML Jung Enn MBTI Tarot Hero "What if I pick six and treat them as editorial?"

Left: ten archetypal systems spread laterally, three interfaces beneath them, all drawn with vanilla JS on a phone. Right: six systems chosen, each given vertical depth — KWML as the pedagogical spine, plus an Atlas layer for cross-system mappings, a Mirror for shadow prompts, a Profile for cross-system tensions, and a Today surface for daily archetype. The decision to go deep was only thinkable after the wide version had shipped.

v2’s grammar. A DESIGN.md enforces a shared visual language across all six systems: KWML uses 3D platonic solids with bloom; Jungian organic forms; Enneagram instruments; MBTI animated cognitive glyphs; Tarot halos; Hero’s Journey silhouettes. Four motion primitives (breath, spin, pulse, shimmer) defined once. Five semantic totem scales (xs–hero, 22–200+ px) with animation budgets. Cards layer frame → field → token. This is the part where the project becomes serious.

v2’s editorial scaffolding. Debates taxonomy (confidence/impact/status fields). Exemplars network with source attributions — /atlas/exemplars was just expanded by 25 figures with a tiered index. A weak-hermeneutic methodology page with pipeline infographics. Citations linked from debates back to bibliography entries — a real graph, not a citation theater.

What +44 commits looks like. The assessment flow. /quiz (landing), /quiz/take (stratified item draw, a Likert scale with a gold spine and warm gradient, section progression, resume/undo), and /quiz/r/[code] — an editorial “Reading” spread with a constellation centerpiece and URL-encoded answers. Feature-vector visualizations (radar + resonance network) wired into all six archetype detail pages, rich snippets across every page, the completion screen previewing your cast and routing into the Reading. The pixel-level polish stayed (Likert spine snapped to whole-pixel rows, axis-label clip fixes) right up to the last commit on Apr 23.

Build to Think verdict. v1 asked can I map every system on a phone? v2 asked what if I pick six and treat them as editorial? — and, with the quiz, finally answered the question the editorial implied: how does someone find their own archetype? The assessment was the last thing built and the only thing that turns a beautiful reference into a usable tool. That it shipped and then went quiet is itself a data point: the project reached completeness exactly as a cross-country move arrived. It is still pre-launch — Vercel-ready, no public domain yet.


The Mods: minecraft-mods

One directory, two projects, two entirely different personalities.

MTL Memories (Forge 1.20.1, Java 17). A nostalgia mod for Montreal and McGill 2004–2008. 14 custom items (poutine, Montreal bagel, smoked meat, Gerts token, Arcade Fire vinyl). 5 quest storylines. Status: exploratory. The quest framework runs, but it’s a foundation without the visual layer — which is roughly the state of memory itself.

LabsCraft (Fabric 1.21.4, Java 21 + a Node.js agent server). An LLM-powered mod simulating an APM internship at “Google Labs” on an AI video product called “Flow.” The centerpiece is Josh Woodward, a PM NPC whose dialogue is generated by Claude Sonnet (Gemini fallback). This is exactly as on-the-nose as it sounds, which is the point.

The mod (46 Java files, 5,391 LOC) sends world state every tick via HTTP to an agent server (13 TS files, 1,394 LOC) running Express on port 3001. Six trigger types (chat, interaction, idle-near-objective, quest-complete, danger, periodic proximity). SQLite stores conversation history, top-5 extracted memories per player, and quest state. Memory extraction every five conversations; summarization at threshold. Josh’s character brief: deadpan PM humor, references to syncs/sprints/P0s/OKRs, max three sentences per turn. Status: shipped — built jar at build/libs/labscraft-1.0.0.jar, 148 unit tests, three Claude worktrees active during the build.

Build to Think verdict. Two modes sharing a disk and nothing else. MTL Memories is pure nostalgia-as-enumeration: the act of listing what to include is the project. LabsCraft is the technically serious frontier — an agentic NPC architecture (perceive → decide → reason → execute) with per-player memory and multi-provider LLM fallback, emerging from iteration.


The Gift: kareemrpg

Shipped on itch.io. A birthday gift for a friend named Kareem. Five learning projects in 16 days, each one existing solely so the next one could exist:

  1. learningproj (May 24) — first GDScript, 25 lines, “what is a node?”
  2. kareemrpg-beta (May 24) — mobile RPG skeleton
  3. dialogictut (May 25) — Dialogic addon + NPC basics
  4. daytworpg (May 25) — 9 scripts, dialogue, audio, NPC/follower systems
  5. dialogictutotrial (Jun 9) — final game: 66 scripts, 68 dialogic files, 29 scenes

Exported as WebAssembly, published on itch.io, embedded at ummerr.com/kareemrpg. The fastest build-to-learn cycle in the portfolio: from zero Godot experience to a published game in 16 days. The learning ladder is the project history — if you opened the directory cold you could reconstruct the syllabus from the timestamps alone.


The Explainer: inference → inference.ummerr.com

Status: Shipped • Commits: 63 • Last commit: Apr 17, 2026 Stack: React 19 · TypeScript · Vite · Tailwind v4 · Lucide React Live: inference.ummerr.com

“The Fun Inference Calculator.” An interactive web explainer for generative AI compute costs across modalities. Unchanged since the last audit — shipped, stable, and still doing its job. All 12 sections live: Frontier Frictions, Lifecycle, Techniques Ladder, Forward Bets, Failure Modes, Unit Swap, Hidden Costs, Cost Drop Tracker, Video Price Watch, Silicon, Batch vs Realtime, Napkin Math Playground.

Build to Think verdict. The third audit doesn’t change the verdict — it reinforces it. A one-day explainer became a six-day site; the “Cost Drop Tracker” could only be imagined after the calculator existed. Specs don’t generate second-order surfaces. Only running code generates second-order surfaces.


The Ritual: bass

Status: Live structure (unshipped domain) • Commits: 10 (+6) • Last commit: Apr 20, 2026 Stack: Next.js (App Router) · TypeScript · Tailwind v4 · pnpm · flat markdown content · zod

Born the day of the last audit, bass got two more days of attention before the move arrived. A personal site that scaffolds a daily 15 minutes of bass practice — not a content library but a daily loop: warm up → skill of the week → fretboard minute → play something fun → log it. Git is the streak tracker. All content is flat markdown.

What the six new commits added: a real tab system. A tab library with a color-per-key palette tied to the circle of fifths; a zod-validated structured tab schema (Phase A); a three-view reader — beat grid / ASCII / fretboard (Phase B); a guided practice path; and a 30-tab library with “Start here” grouping. Then, on Apr 20, it stopped.

What shipped in v1. / — the daily loop: five numbered steps + streak + 90-day heatmap + explore nav. /lessons — ten beginner lessons with status badges (not-started / learning / practicing / comfortable / retired). /lessons/[slug] — lesson detail. /fretboard — fretboard explorer, beginner-default (neutral dots, note-name labels, four presets: All notes / C major / A minor / E minor pentatonic); “Show advanced” reveals 12 roots, 5 scales, degree/interval labels. /drills/fretboard-notes — silent note-recognition drill, two modes (Name→Fret, Fret→Name), 12 prompts per round, single-string SVG. /log — copy-template flow for today’s practice entry, filename hint, recent-entries list. URL presets supported: /fretboard?preset=c-major.

The pedagogy. A PLAN.md file — 15KB, six build phases, references to BassBuzz / Scott’s Bass Lessons / StudyBass / TalkingBass / Justin Guitar / Berklee / Fogg & Clear habit-formation science — enumerates the thesis before any code:

“The site is not a content library. It is the scaffold around Ummerr’s daily 15 minutes with the bass in hand.”

Six principles are written down explicitly: beginner-first defaults, one next action, silent-first (no audio in v1), git is the database, progress must be visible (heatmap, lesson-status transitions, streaks), pedagogy over features. The site’s home page is the five-step loop. Not a dashboard of features — the loop itself.

The AGENTS.md reveal. A single file in the repo, eight lines:

“This is NOT the Next.js you know. This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ before writing any code. Heed deprecation notices.”

That one file — a one-sentence correction to the agent’s priors — is a complete Build to Think artifact: the author noticed the tool’s training data was stale, wrote down the correction in eight lines, and moved on. No meeting. No ticket.

Build to Think verdict. The clearest Build to Think instance in the entire portfolio, because the product is literally the loop that Build to Think advocates: a daily 15 minutes with an instrument, logged in markdown, streak-tracked by git. The site isn’t for visitors. It’s a personal scaffold that happens to be public because it’s easier to ship Next.js on Vercel than to build a bespoke tracker. Five small things, ≈15 minutes, skip any of them. Showing up is the win.

That it paused mid-stride doesn’t undercut the thesis — it’s a personal scaffold, and personal scaffolds wait for you. The tab reader is now there for whenever the bass comes out of its case in the new apartment. bass joins bookmarks, inference, and the Dopamine Rat as a tool whose use is indistinguishable from its design.


The Test Bench: VidMetaPrompt

A framework for transforming high-level creative video ideas into structured 7-component prompts for Veo-3 generation. Modular: Analysis Engine, Knowledge Base, Character Builder, Generation Engine, Quality Validator. 15+ implementation modules; UI scaffolds exist and are empty. Where bookmarks discovered its shape through deployment, this one discovers its shape through tests. Same principle, different probe.


Footnotes: smaller projects

cursorMint — Personal finance tracker. Loads bank CSVs, standardizes transactions, stores in SQLite, plots spending. ~350 lines. No git. Functional utility — it exists because the alternative was a SaaS that would have cost more than the groceries it tracked.

film — Astro 6 photography portfolio scaffold. Single commit. Template stage.

StreakUp — Cloned from rezahedi/StreakUp as an architectural reference. This is not my code. A production-quality habit tracker studied for patterns (CRUD flow, streak lifecycle, timezone handling, Prisma schema design).

testExport — Godot web export test. Binary artifact. Not a development project; it’s evidence.

dopRatTest — An empty directory. The most honest project in the portfolio. It knows it doesn’t exist.


The Build-to-Think Scorecard

Every project started without a spec. The interesting column is the right one — what only became visible because building forced it into the open.

Spec → Reality — the gap building made visible

bookmarks a Chrome ext for bookmarks a competitive-intelligence desk Dopamine Rat a point tracker "measured recovery" — reads your body archetypes v1 "can I build on a phone?" 3 interfaces, mobile-native archetypes v2 "pick fewer, go deeper" a quiz-complete Three.js platform inference a one-day explainer a 12-section pricing handbook LabsCraft "what if an NPC had memory?" a full agentic architecture, per-player kareemrpg "learn Godot for a birthday" 5 projects in 16 days, shipped MTL Memories "what do I remember?" enumeration as the project VidMetaPrompt started with tests discovering shape through TDD bass "15 min of bass a day" site = the loop · git = the streak ummerr.github.io started 11 years ago still the place every project lands sf ← NEW "a log of my move to SF" a LiDAR atlas + drivable arcade city golf ← NEW "render the courses I play" a DEM pipeline + 3D viewer + sim SPEC REALITY

Every project started with code, not a spec. Constraints taught. Writing followed building. The arrows are the gap building made visible — and the two newest, sf and golf, are the clearest of all: you cannot design a move into a repository, you can only build it.


Closing

Five audits in, the lineage has a shape: a heartbeat that quickens when the author is processing something — a move, a launch, a product he can’t stop thinking about. This round the heartbeat returned after nine days, and what it pumped out was unmistakable. A Google PM, off the clock and at zero cost, rebuilt his own product as a game and measured his own launch as evidence, because for this builder that is what understanding something feels like. flowtcg is the product turned into a loop you can lose. bookmarks/flow-brief is the launch turned into a memo you can act on. sf and golf are the counterweight — a life, rendered — proof the portfolio isn’t only parallel research.

The headline isn’t “a PM has hobbies.” It’s that the side-project portfolio has quietly become a second, unsanctioned product org pointed at the same problems Google ships — staffed by one person, running on free tiers, moving faster than the audit that tries to keep up with it.

The day job didn’t leak into the side projects. The side projects walked up to the day job and shook its hand. No design doc could have described any of it — because none of it existed until the author started building.


This audit was generated by 4 parallel Claude Code Explore agents across 3 filesystem locations and 20 repositories, inspecting ~1,084 commits. Zero permission prompts, by design. To regenerate, run /audit from ~/CodeProj/.