Day 3 in retrospect: four workstreams, two counted launches, one very full day
The day the factory engines came online, a side-quest went live, a real product attached its domain, and the news aggregator stopped looking like a dev tool. Four streams. Forty-one commits across three repos.
A note on this post before we start: Day 3 was a four-stream day, not a one-stream day, and the first version of this recap I published mid-afternoon got that wrong. It only told the LaunchCost + Parent Care story because that was the only stream I had clean git timestamps for at the time. The version below is the rewrite — with the LocalShoot Houston-launch closing arc, the Handscript domain-attach + persistence ship, and the TrustCore Media editorial refresh + §5 gate close-out all in their proper places.
Day 1 was me writing all morning, the agent writing all afternoon, one site live by midnight. Day 2 was a parallel-pair scaffold day with five working hours and an aesthetic rebuild. Day 3 is the third pattern, and the one I’m going to keep arguing for: a day where four products move in parallel because the factory rules are clear enough to keep each one moving without the others jamming. The honest version of what that looked like is below.
The big picture
By end of Day 3:
- 2 counted launches on the 50by50 scoreboard: LocalShoot (
localshoot.app) and Handscript (handscript.app). - 1 live but not yet counted: TrustCore Media (
trustcore-media.vercel.app). Sitting at 8/10 on the §5 launch gate; the remaining two items (GA4 measurement ID + Search Console verification) are paste-in-Vercel work for Thursday. - 2 in build for Friday: LaunchCost and Parent Care, both with working engines, tests passing, supporting articles written, and a clean smoke-test-and-ship runway.
- Forty-one commits across three repos (Birthday-Challenge, trustcore-media, Handscript). Plus a separate LocalShoot repo, where the bulk of work happened.
Day 3 of 132. 129 days remaining. 2/25 minimum, 2/50 stretch. If Friday lands the three building sites we’re at 5/25 by end of Day 5 — ahead of the Path C cadence.
Stream 1 — The 50by50 factory engines
This was the planned stream. I wrote a long handoff brief at noon and the coding agent executed against it. Seven commits in eighteen minutes. Then the polish + doc passes that compounded through the rest of the day.
12:25 PM — Status flip, handoff goes in
f790024 — Day 2 status flipped to done, Day 3 queued. Last user-typed commit of the day on this stream. The handoff brief itself ran longer than I expected: standing rules, all eleven TrustCore coding-standards records inlined from Pinecone, Tier 1 / Tier 2 / Tier 3 priorities with explicit “Friday-launch-blocking” tagging on the two engines, decisions-already-made I didn’t want the agent to relitigate, repo-specific quirks (Vite version pin, prettier ignore, eslint import-order strictness, the subpath-export pattern), and the two questions I owed me-the-user later (GA4 IDs, Search Console verification path).
12:27 PM — 00fcb3f LaunchCost calc engine math + 25 tests
Pure TypeScript module, no I/O. Five inputs (team size, stack, paid distribution, office mode, legal setup) return {low, mid, high} totals + a per-line breakdown with rationale notes. Defaults sourced from BLS wage data, public SaaS list prices, Apple’s $99 developer fee, three public Delaware LLC filings.
The thing I want to flag about this commit is the discipline that made the next four cheap: no I/O, no DOM, no fetch in the calc module. That’s how the same module ended up powering the homepage UI and the CLI with zero drift between them.
12:32 PM — d99100c Wire calc into the homepage
LaunchCost stops being scaffolding here. SSR baseline computed at build time. Client script that reads every form select, runs calculate() on change, patches the result card + breakdown in place. No framework, no state library — three event listeners and a render function.
Manual hand-check: team→3, paid→heavy, office→leased. Mid jumps $42,180 → $139,780. The math hand-confirms: $93,600 founder time + $2,640 hosting + $18,000 leased office + $24,000 heavy paid + $1,540 legal/accounting/domain. Eyes-on-actual-dollars verification I trust more than a test.
12:33 PM — 49e9ef9 LaunchCost CLI (cs-08)
The coding standards say every feature gets a CLI. Five minutes after the homepage was working, the CLI shipped. npx tsx scripts/calc-cli.ts --json emits machine-readable JSON. --team 99 exits 2 with [calc-cli] --team must be 1, 2, or 3 (got "99"). Fix: --team 2. on stderr.
This matters more than its size. The calculator is now scriptable for agents — anything from Paperclip to a future autoresearch loop can ask “what does a 3-person mobile team’s year-one look like” without parsing HTML.
12:37 PM — 0589961 Parent Care checklist engine + 30 tests
The bigger engine. Twelve questions across four domains (daily living, medical, finance, support), each answer weighted 0–3 concern. Five conditional follow-ups that surface inline when a base answer flags a specific risk — for instance, “needs daily help bathing” triggers “have they fallen in the last six months.” Follow-ups don’t contribute to the readiness score; they sharpen the agency-call packet only.
Four-band readiness scoring at 25 / 50 / 75 percent boundaries: stable → watch → plan → urgent. The agency-call packet only generates from concerns at level ≥ 2, so a stable family gets a clean result, not a generic checklist dump.
12:41 PM — 1e4b780 Parent Care UI + client-side PDF
End-to-end. Twelve numbered radio sections, four per domain. Result panel updates live — band, per-domain percent bars, flagged-concern summary in plain English, agency packet appearing only when earned by the answers.
PDF export via window.print() + a print-only stylesheet. No library dependency, no data leaves the device. The print stylesheet inlines its own Source Sans / serif typography to match the design system.
Privacy posture made explicit in the result panel copy: “Answers stay on your device. This entire page runs on your device.” No analytics fire on answer values.
12:45 PM — 3e102cf All four supporting article stubs filled
Roughly 3,500 words across the four nanocluster supporting pieces. Hosting Costs names the egress trap explicitly (“100GB/month on AWS S3 is $9 in egress, which seems trivial until you multiply by 12 and remember it’s per region”). Stack Tiers compares Managed / Serverless / DIY with cost shapes in dollars. Agency Questions ships twelve specific things to ask with the answer shape to expect. Independent vs Agency walks five structural differences with California 2026 loaded-cost math.
The Parent Care articles carry a “nothing on this page is medical, legal, or tax advice” disclaimer. The four placeholder reviewer names in the Methodology block are now flagged in the article body as pending consent — so any visitor reading the page sees the qualifier instead of relying on a hidden STUB comment.
Then the polish + doc passes (12:47 PM onward)
- 12:47 PM — First version of this recap published (
80dbe4b). It only covered the 12:25–12:45 window because that’s all I had clean evidence for. You’re reading the rewrite. - 12:59 PM —
54677f4LaunchCost layout fix. Removed the hero scene image that was bisecting the calculator inputs from the result card. Three-second design call: image gone, ~150KB JPEG out of critical render, tool→result reads as one continuous block. - 1:03 PM —
8ffb3b9Hub/roadmaplink fix. The card title was only wrapped in an anchor whens.domainwas set; Handscript hadstaging_urlbut no domain, so its card was unlinked. Added a fallback that usesstaging_urland surfaces a quiet “(staging ↗)” cue. (Soon to be moot — Handscript’s actual domain attached this evening.) - 1:47 PM —
e594251Daily-card update: nine Day 3 tasks marked done with one-line notes each, three deferred, status flipped toin_progress. - 4:54 PM —
b1c80eeFirst doc pass: roadmap.yaml, portfolio tracker, CHANGELOG, both LAUNCH_LOGs.
Stream 2 — LocalShoot (Houston launch arc closes)
This stream actually started Monday night and finished today. Pulling the commit history into one place:
Monday 5/12 night — Session 1 (9:43 PM → 11:43 PM, ~2h)
Spec arrived around 9:30 PM Eastern. First scaffold commit at 9:43 PM.
| Time | Commit | What |
|---|---|---|
| 9:43 PM | 9464188 | Initial Next 16 + Tailwind scaffold |
| 9:54 PM | 6 commits in 75 seconds | Toolchain (ESLint, Prettier, Husky, strict TS), Supabase schema migration, lib + Button primitive, homepage + Houston page, README |
| 10:21 PM | 7962b28 2086f2d | Wired Supabase clients, Houston map renders live pins from DB |
| 10:43 PM | 3323398 | Domain bought mid-session — full rebrand “Shot Spot” → “LocalShoot” |
| 10:58 PM | c0f1a2d | First 10 Houston seed locations + apply-sql CLI |
| 11:32 PM | 25f6f76 | Brand Kit applied (warm paper, Flare orange, Mint, Bricolage, custom map pins) |
| 11:38 PM | 45580a7 | Location detail pages |
| 11:43 PM | 3d35aee | Submit form + admin moderation queue |
End of Monday: site live with 10 seeded spots, brand kit applied, submission flow working. Eleven commits in two hours.
Tuesday 5/13 — Session 2 (11:56 AM → 4:23 PM, ~4.5h with debugging)
| Time | Commit | What |
|---|---|---|
| 11:56 AM | 5fb7505 | 7 “Coming soon” stubs + newsletter form skeleton |
| 12:41 PM | 546fca2 | Real Wikimedia Commons photos for 7 of 10 spots |
| 1:01 PM | 5e3f1b2 | Minimal “Photo: |
| 1:15 PM | b33c5c4 | Pivot newsletter from API → Beehiiv loader script (Cloudflare blocks server POSTs) |
| 1:47 PM | 7394bf8 | First deploy-hang fix attempt (force-dynamic) |
| ~1.5h | Dead zone debugging Vercel “limited” status — every deploy stuck at UNKNOWN | |
| 3:19 PM | 789f30b | Real fix: removed generateStaticParams + force-dynamic conflict; surfaced a [email protected] git config issue too |
| 3:31 PM | 783537e | Filter chips URL-driven + Unsplash fallbacks for last 3 photos |
| 3:52 PM | 0325b44 | Seeded 20 more Houston locations → 30 total, all with photos |
| 3:54 PM | bbe3e70 | Caption cleanup (strip location info from author names) |
| 4:11 PM | 98a379d | Creator contributions: “Shot here” links per location + OG scraper + admin moderation |
| 4:23 PM | ec71e72 | /tips live feed of all contributions across the city |
End of afternoon: 30 spots with real photos, working filters, creator contributions, /tips magazine, all deployed.
Tuesday 5/13 — Session 3 (5:22 PM → 8:19 PM, ~3h)
| Time | Commit | What |
|---|---|---|
| 5:22 PM | a054120 | Business owner magic-link auth foundation (/business/login, /auth/callback, /business/dashboard) |
| ~2h | Design pass on For Businesses + challenges feature + accountability + verification, plan locked | |
| 8:19 PM | c516587 | Creator accounts: /login, /me, Save Spot button works, signed-in @handle chip in header |
LocalShoot totals
- Wall clock from spec → tonight: ~22h 36m
- Active build time across 3 sessions: ~9.5 hours
- Commits: 26
- Lines shipped: ~4,500 (rough — SQL migrations, components, server actions, scripts)
From “text to an old friend about an idea” to “live product with 30 locations, creator accounts, and a moderation pipeline” in under 10 hours of actual work. Counted on the 50by50 scoreboard. Note in the roadmap card honestly flags it as a side-quest custom build — not factory template — because build-in-public means the scoreboard tells the truth about how each launch happened.
Stream 3 — Handscript flips live
12 commits across three sessions in the Handscript repo today. 3,880 insertions / 821 deletions across 35 files. Started the day with a partially-working pipeline that returned a TTF binary and no UI. Ended with a live, auth-gated, custom-domained product at handscript.app.
Pipeline + initial deploy (3:00 PM → 3:40 PM)
- 3:03 PM —
3d3f289Pipeline rewrite: per-corner Vision detection, char-class font assembly (909 ins / 589 del, 12 files). End of yesterday’s debugging: Vision was anchoring to page corners not registration marks, dewarp was off, fonts came out garbled. Today’s fix: per-corner Vision crops + Python centroid refinement + character-classified font assembly. - 3:10 PM —
3958775HTTP server for live deployment. Wrapped the pipeline in an Express server (POST /generateaccepts a multipart photo, returns TTF binary). - 3:11 PM —
6d6c3d3/createpage that uploads + downloads. Initial sync MVP — client component, photo upload, fetch-from-worker, blob download. - 3:33 PM —
c291c9eSite nav,/templatepage, 3-step flow. Shared<SiteNav />+<SiteFooter />mounted in root layout. Home redesigned around “Download template → Fill + photo → Upload + download”. - 3:37 PM —
1ace71cRecommend Sharpie instead of pen. Thin pens produced skinny illegible fonts; the discovery led to a three-place copy update (PDF instruction, /template page, /create tips).
Somewhere in here, handscript.app got wired via Cloudflare DNS API → Vercel.
Hardening + persistence (4:00 PM → 5:00 PM)
- 4:27 PM —
554bea6Rate limits, concurrency cap, daily abuse cap. Per-IP 5/hr + 20/day, MAX_CONCURRENT=3, daily total 500./healthexposesinFlightanddailyUsed. Smoke-tested: 3rd request in a row returns 429 with the right message. - 4:39 PM —
e01bf51The big commit (812 ins / 284 del, 12 files). Worker now requires Supabase JWT, generates.ttf/.otf/.woff2plus a preview PNG (the printed template re-rendered with the new font), uploads everything to Supabase Storage at<user_id>/<font_id>/, inserts afontsrow, returns{font_id}. Web/createbecomes auth-gated; new/fonts/[id]shows preview + 3 download cards; new/fontslists past fonts. SiteNav becomes auth-aware. - 4:43 PM —
4223176Old scaffolded dashboard redirected to /fonts. - 4:47 PM —
d973058Bump worker to Node 22 for native WebSocket. First Railway deploy of the persistence code crashed at startup: supabase-js’s realtime client requires WebSocket which Node 20 doesn’t ship. - 4:56 PM —
9e6cbb9Email + password sign-up and sign-in. Google OAuth attempt failed (no provider configured); replaced with email/password usingadmin.createUser+email_confirm: trueso sign-up is instant.
Polish (8:00 PM → 8:30 PM)
- 8:06 PM —
8cc53c7Capture name at signup + simple profile page. Name flows throughhandle_new_usertrigger intoprofiles.display_name. SiteNav shows the name (clickable to /profile). - 8:29 PM —
4b0ba38Per-char anchors + reject text-strip cells. Punctuation tuning. Each char gets a precise vertical anchor (top, midx, midhigh, near-baseline, below). New pre-filter rejects bitmaps that look like horizontal text strips bled into a cell — these render as missing-glyph boxes (▢) instead of smeared blobs.
Handscript verified end-to-end
End-to-end run twice today with two different writers’ template photos. Photo → font → install in ~6 seconds via the live worker. Production performance was 4–5x faster than dev (25–30s) — still investigating why, but consistently good.
Counted on the 50by50 scoreboard as launch #2. Card on /roadmap links straight to handscript.app.
Stream 4 — TrustCore Media: editorial refresh + §5 gate close-out
Three commits in the TC Media repo today.
3:18 PM — 7f7215a Editorial refresh
User-prompted: “real crappy looking, needs help.” Diagnosis: not broken, just no personality. Generic dark-mode dashboard aesthetic, no editorial voice, dual amber+indigo accents fighting each other, At-a-Glance card overloaded with three columns of stats + trending + latest, masthead a plain wordmark with no identity.
The refresh, keeping Next.js 16 + React 19 + Tailwind v4 architecture:
- Warm paper-black palette (
#0F0D0B/#171513/#1C1916), warm cream text, single terracotta accent (#D97757). Dropped the dual-accent system — category is signaled only by small mono kicker labels (CRYPTO / AI) so the eye stays anchored on one accent. - Added Newsreader serif for headlines + lede + section heads + editor’s deck. Geist kept for UI body. Mono kickers for labels.
- Masthead now reads as a real wordmark: serif “TrustCore” + italic terracotta “Media”, dateline + edition info in mono, italic-serif editor’s deck (“Calm signal from the crypto and AI firehoses — hand-picked from 13 sources, every morning. No commentary, just what moved.”).
- At-a-Glance → Today’s Brief lead: two ledes (one crypto, one AI) with kicker labels, italic-serif headlines, snippet, source + time in mono. Trending row on a thin top rule below.
- Top Stories → magazine StoryColumns with a feature lede (16:9 image + serif headline + snippet + kicker) and three secondary stories below.
- “Full Feed” → “The full file — Every headline, in order”: calmer rows, category kicker, headline, source + time.
- Sidebar restructured into stacked panels (kicker over hairline).
- Subscribe form becomes an editorial inset on a left accent rule.
- Footer becomes a colophon.
Build clean, typecheck clean, lint clean (one apostrophe escape later). Looks like a publication now, not a dev tool.
4:43 PM — 6901c19 Lint warnings + CryptoSlate 403
Two follow-ups from the refresh:
- Raw
<img>swapped tonext/imagewithunoptimized+fill+sizes. Bandwidth profile unchanged, layout-shift prevention gained. - CryptoSlate had been returning 403 to every request from rss-parser. Confirmed via curl that Cloudflare blocks the polite-bot UA on this network regardless of UA strings. Added a native-fetch fallback path with a full browser UA + raw-XML entity sanitization. CryptoSlate now renders in the source list (200 → 210 items). The sanitizer also gets past LangChain Blog’s malformed
&entities — though LangChain’s URL turns out not to be valid RSS, so it still fails on the “not RSS 1 or 2” check.
8:35 PM — 146bc1f §5 launch-gate close-out
Four of the five gate items I could close without user input shipped in one commit:
- #4 SEO hygiene —
app/robots.ts(Allow all, Disallow /api/, sitemap reference, env-driven host),app/sitemap.ts(homepage hourly priority 1 + /privacy yearly),layout.tsxgainsmetadataBase,alternates.canonical, OpenGraph + Twitter cards. - #6 Analytics framework —
src/components/analytics.tsx. GA4 + Search Console verification component. Both inert untilNEXT_PUBLIC_GA4_IDandNEXT_PUBLIC_GSC_VERIFICATIONenv vars are set in Vercel. Privacy defaults wired:anonymize_ip: true,allow_google_signals: false,allow_ad_personalization_signals: false. - #9 Compliance footer — Footer gains Privacy + Contact + 50by50 nav links, outbound-affiliate disclosure, publisher-attribution line. New
/privacypage with full statement: what we collect (GA4 anonymized pageviews, subscriber email, standard Vercel logs), what we don’t (no Pixel, no fingerprinting, no session replay), source attribution, contact, affiliate disclosure. Last-updated stamp. - #10 Launch log — New
LAUNCH_LOG.mdat the TC Media repo root following the 50by50 template: persona, core asset, MVP pages, CTA, monetization, privacy posture, full §5 gate scorecard, step-by-step “to flip counts to true” instructions, kill-clock, Day-3 EOD state.
TC Media now sits at 8/10 on the gate. The two remaining items (analytics + Search Console) are paste-the-IDs-in-Vercel work for Thursday. Once those land, single one-line edit to roadmap.yaml (counts_toward_total: true) flips TC Media to count #3.
Doc passes and decisions logged
Two large doc passes today, both at EOD windows. One after the LaunchCost + Parent Care burst (4:54 PM) and one after the LocalShoot / Handscript / TC Media flips (8:04 PM, MasterPlan; 8:11–8:36 PM, three roadmap entries).
The CHANGELOG gained five Day 3 strategy-level decisions:
- Agent-execution day pattern — handoff rules that make it work. Standards inline (paste, don’t cite). Tier 1 / 2 / 3 explicit. Decisions-already-made section. Honest “what slips if it slips” budget. Verbal handoffs don’t work.
- No email gate on calculator results. Free results, soft capture via
BeforeYouLeaveCTAbelow result. The “five questions, honest range, no signup required” promise is a structural commitment. - Reviewer-consent policy. Every named reviewer with a credential needs real, written consent on file before any deploy. Placeholder names get credential-only entries or stay hidden until consent. No invented person on a production page.
- Metric-gated domain-purchase rule. Stay on
*.50by50.devsubdomain through Week 1. Buy + 301-redirect in Week 2 only if metrics earn it: ≥500 unique visitors AND ≥20 primary-action completions AND ≥5 email signups for the week. window.print()+ print stylesheet as the standard pattern for client-side PDF. No PDF library dependency, no data leaves the device, modern browsers all expose “Save as PDF” in the native dialog.
MasterPlan §15 gained a “Day 3” subsection capturing these five in their canonical form. §16 gained a Day 3 entry pointing at the full CHANGELOG.
What slipped to Thursday
- GA4 measurement IDs + Search Console verification for both 50by50 spokes AND TC Media. Waiting on me-the-user to provide IDs.
- TC Media
counts_toward_total: trueflip — depends on those analytics + SC IDs + a real contact email replacing the[email protected]placeholder in the footer + privacy page. - Parent Care reviewer-consent calls. Names remain placeholder pending real consent on file.
media.50by50.devDNS attach for TC Media.- LangChain Blog feed URL fix in TC Media. Their configured URL turns out not to be a valid RSS feed; needs a real feed URL or removal from the source list.
- Handscript punctuation polish — one text-strip cell is still slipping through the filter; either tighten the filter or build a “no-fly zone” mask over the template’s static content regions.
The thing I want to say about today
The first version of this recap missed three of the four streams because I wrote it at 12:47 PM and only knew what the agent-execution stream had shipped. The actual day kept going: editorial refresh in the afternoon, LocalShoot creator-accounts arc in the evening, Handscript flipping live, TC Media closing eight of ten gate items.
What made it possible to have four products moving in one day was that the factory rules don’t require my attention to function. The coding standards exist as 11 records I can paste into a handoff. The §5 launch gate exists as 10 numbered items I can score against. The nanocluster pattern exists as a doc I can point at. The decisions log exists as something I can append to. When the rules are durable, each new product can borrow them without me being the routing layer.
That’s the version of “shipping fast” I want to be testing in this sprint. Not “lots of code per hour” — anyone can do that, briefly, and pay for it in incoherence two weeks later. The thing I’m testing is “ship the right code per hour because the rules are clear” — and Day 3 was the first day where the test ran on four products at once and didn’t fall over.
Day 3 of 132. 129 days remaining. Two counted launches on the board. Three more building.
Tomorrow: GA4 + Search Console wiring across the three pending sites, the reviewer-consent calls, a Handscript polish window, and the Friday-launch dry run for LaunchCost + Parent Care. Detailed checklist lives in day-004.md.
Follow the build
One email a week. Real numbers, real lessons. No hype.
Unsubscribe in one click. No selling, no sharing.