<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Claudia Website!</title>
 <link href="/atom.xml" rel="self"/>
 <link href="https://w.laudiacay.cool/"/>
 <updated>2026-02-13T00:25:51+00:00</updated>
 <id>https://w.laudiacay.cool</id>
 <author>
   <name></name>
   <email></email>
 </author>

 
 <entry>
   <title>How We Escaped Dev Environment Hell (And Made It Agent-Friendly)</title>
   <link href="https://w.laudiacay.cool/2026/01/02/dev-environment-escape.html"/>
   <updated>2026-01-02T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2026/01/02/dev-environment-escape</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Building a multi-worktree development platform that humans and Claude can both navigate&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-problem-death-by-a-thousand-paper-cuts&quot;&gt;The Problem: Death by a Thousand Paper Cuts&lt;/h2&gt;

&lt;p&gt;Every startup has dev environment debt. Ours was getting bad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The symptoms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; with 47 targets, half undocumented, some broken&lt;/li&gt;
  &lt;li&gt;Three different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup-env.sh&lt;/code&gt; scripts that contradicted each other&lt;/li&gt;
  &lt;li&gt;Devs running with mock API keys, then wondering why integrations “worked locally but not in staging”&lt;/li&gt;
  &lt;li&gt;“How do I see the logs?” asked weekly in Slack&lt;/li&gt;
  &lt;li&gt;“Which port is the API on again?” followed by someone sharing a screenshot of their terminal&lt;/li&gt;
  &lt;li&gt;Postgres running on 5432… unless you’d changed it… and forgot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Then we added Claude Code to the mix:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every dev now had 2-5 Claude worktrees running simultaneously. Claude would spin up the dev environment, start working, and then… another Claude instance would start the same services. Port conflicts everywhere. Database migrations stomping on each other. One agent’s test run nuking another agent’s seed data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then there’s just… the sheer number of services:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standing up the dev environment means: Postgres (seeded with test data), Elasticsearch (synced from Postgres), Redis, Celery workers, Celery beat, the API, the frontend, email testing, log aggregation, and monitoring. Miss one and something fails silently. Get the startup order wrong and migrations break.&lt;/p&gt;

&lt;p&gt;And then you have to replicate all of that in CI. And make it work on everyone’s machine - M1 Macs, Intel Macs, the one guy on Linux. I wanted to cry constantly.&lt;/p&gt;

&lt;p&gt;We used to use Supabase. Endless nightmares. Docker + Supabase local dev was a constant battle. Opaque errors, magic auth flows, platform-specific behaviors that worked in their cloud but broke locally.&lt;/p&gt;

&lt;p&gt;Here’s the thing I’ve learned: &lt;strong&gt;pre-AI, heavy platforms made sense.&lt;/strong&gt; Supabase, Firebase, Railway - they handled the complexity you couldn’t. Deploys, migrations, dev environments - too much to build yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-AI, lightweight composable tools win.&lt;/strong&gt; Now I can just use:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Postgres with SQLAlchemy and Alembic (no platform magic, just SQL)&lt;/li&gt;
  &lt;li&gt;Celery with state graphs for complex jobs (stored in the database, fully inspectable)&lt;/li&gt;
  &lt;li&gt;OTEL for everything (old, boring, standardized)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No vendor lock-in. No platform-specific behaviors. Just well-documented open source tools that Claude actually understands because they’ve been around forever.&lt;/p&gt;

&lt;p&gt;Building our own deploys? Claude writes the Terraform. Building our own dev environment? Claude helps debug the docker-compose. The platforms were training wheels. With AI, I don’t need training wheels - I need composable primitives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then we moved to VPC:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We put RDS behind a private subnet (correctly!). But now nobody could connect to the database locally. The bastion host existed but nobody knew how to use it. Someone wrote a script, it got lost, someone rewrote it differently.&lt;/p&gt;

&lt;p&gt;I spent more time debugging dev environments than building features. Something had to change.&lt;/p&gt;

&lt;h3 id=&quot;the-human-cost&quot;&gt;The Human Cost&lt;/h3&gt;

&lt;p&gt;Here’s a subset of the people on my team:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The frontend dev.&lt;/strong&gt; Great at React, ships UI fast, doesn’t want to know what an OTEL collector is. Shouldn’t have to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cofounder.&lt;/strong&gt; His main job is sales and customer-facing work. When he codes, it’s rapid in-and-out - a customer reports a bug, he dives in, fixes it, deploys, back to calls. Not deep work. He does not have time to debug why Docker isn’t finding a volume mount.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me.&lt;/strong&gt; I built the infrastructure. I understand the Dockerfiles, the Terraform, the VPC topology. Which means every env question lands on me.&lt;/p&gt;

&lt;p&gt;The pattern was brutal:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;I’d make an infrastructure improvement (good!)&lt;/li&gt;
  &lt;li&gt;Someone would pull main&lt;/li&gt;
  &lt;li&gt;“Hey, the API won’t start anymore”&lt;/li&gt;
  &lt;li&gt;I’d context-switch from feature work to debug their env&lt;/li&gt;
  &lt;li&gt;Find the issue (missing env var, stale container, whatever)&lt;/li&gt;
  &lt;li&gt;Fix it for them&lt;/li&gt;
  &lt;li&gt;Different person same issue: “Hey, the API won’t start anymore”&lt;/li&gt;
  &lt;li&gt;Repeat for a week&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every change to the dev environment triggered a support avalanche. I became the bottleneck. I was scared to improve anything because of the support cost.&lt;/p&gt;

&lt;p&gt;And these weren’t dumb questions. “How do I see the Celery logs?” is reasonable. “What port is Elasticsearch on?” is reasonable. “How do I connect to the dev database?” is reasonable. The problem was that the answers weren’t obvious, so every reasonable question came to me.&lt;/p&gt;

&lt;p&gt;The frontend dev shouldn’t need to understand Docker networking to see why their API call is failing. The cofounder doing a quick bug fix shouldn’t need to remember the bastion host SSH command. They should be able to be productive immediately and get back to their actual jobs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real cost wasn’t my time - it was their momentum.&lt;/strong&gt; Every “hey quick question” interruption for them was a context switch away from the customer problem they were solving. The dev environment was actively slowing down customer response time.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-insight-dev-environment-as-product&quot;&gt;The Insight: Dev Environment as Product&lt;/h2&gt;

&lt;p&gt;I realized our dev environment wasn’t a utility - it was a product. And like any product, it needed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Discoverability&lt;/strong&gt;: New devs (and Claude) should find everything from one place&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: Multiple instances shouldn’t interfere with each other&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Observability&lt;/strong&gt;: Logs, traces, and debugging tools should be obvious&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Not READMEs that rot, but integrated docs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if spinning up a dev environment was as simple as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd project &amp;amp;&amp;amp; make up&lt;/code&gt;? What if every worktree got its own URL? What if Claude could navigate it all without asking me?&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-architecture&quot;&gt;The Architecture&lt;/h2&gt;

&lt;h3 id=&quot;traefik-one-port-many-services&quot;&gt;Traefik: One Port, Many Services&lt;/h3&gt;

&lt;p&gt;The core insight: use a reverse proxy to route by hostname, not port.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://supplyco-dev.localhost/api      → FastAPI container
http://supplyco-dev.localhost/frontend → Vite dev server
http://supplyco-dev.localhost/docs     → MkDocs documentation
http://supplyco-dev.localhost/logs     → Grafana/Loki
http://supplyco-dev.localhost/flower   → Celery task monitor
http://supplyco-dev.localhost/mailpit  → Email testing UI
http://supplyco-dev.localhost/kibana   → Elasticsearch UI
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Different worktree? Different hostname:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://supplyco-feature-x.localhost/api
http://supplyco-feature-y.localhost/api
http://supplyco-bugfix.localhost/api
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All running simultaneously. No port conflicts. The directory name becomes the hostname prefix automatically via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOSE_PROJECT_NAME&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# docker-compose.dev.yml (simplified)&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.routers.${COMPOSE_PROJECT_NAME}-api.rule=Host(`${COMPOSE_PROJECT_NAME}.localhost`)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;PathPrefix(`/api`)&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-api-strip.stripprefix.prefixes=/api&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Traefik reads Docker labels, discovers services automatically, routes based on hostname + path. Zero config per worktree.&lt;/p&gt;

&lt;h3 id=&quot;the-landing-page-everything-in-one-place&quot;&gt;The Landing Page: Everything in One Place&lt;/h3&gt;

&lt;p&gt;When you visit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://supplyco-dev.localhost/&lt;/code&gt;, you get a landing page with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Links to every service (API docs, frontend, logs, etc.)&lt;/li&gt;
  &lt;li&gt;A &lt;strong&gt;worktree dropdown&lt;/strong&gt; that auto-discovers all running instances from Traefik&lt;/li&gt;
  &lt;li&gt;Service health indicators (FastAPI response time, Celery task counts)&lt;/li&gt;
  &lt;li&gt;Quick links to documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/devenv-post/landing-page.png&quot; alt=&quot;The SupplyCo Dev landing page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The dropdown queries Traefik’s API to find all projects with running services. Switch between worktrees without remembering URLs.&lt;/p&gt;

&lt;p&gt;There’s also a &lt;strong&gt;Remote Environment Tools&lt;/strong&gt; section for live incident debugging. DEV/PROD toggle, and pre-written prompts you can paste directly into Claude:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“Query Logfire for ERROR level logs in the last hour”&lt;/li&gt;
  &lt;li&gt;“Query Logfire for API requests over 5s in the last hour”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/devenv-post/prod-debugging.png&quot; alt=&quot;Production debugging tools&quot; /&gt;&lt;/p&gt;

&lt;p&gt;One click to copy the database tunnel command, one click for the password from Secrets Manager. Production incident? Open the landing page, toggle to PROD, paste the commands into Claude, start debugging. No scrambling to remember how to connect.&lt;/p&gt;

&lt;p&gt;Claude loves this. Instead of “what port is the API on?” it just goes to the landing page.&lt;/p&gt;

&lt;h3 id=&quot;shared-observability-stack&quot;&gt;Shared Observability Stack&lt;/h3&gt;

&lt;p&gt;Here’s the thing about logs: you need them when things break. Which is exactly when you don’t want to be setting up logging.&lt;/p&gt;

&lt;p&gt;We run a single observability stack shared across all worktrees:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Alloy (log collector)
    ↓
Loki (log storage) ← labeled by project + service
    ↓
Grafana (UI) ← accessible at /logs on every worktree
    ↓
Tempo (traces) ← for distributed tracing
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Every container gets labels:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;project=${COMPOSE_PROJECT_NAME}&quot;&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;service=api&quot;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# or celery-worker, postgres, etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alloy scrapes Docker logs and tags them automatically.&lt;/p&gt;

&lt;p&gt;The key: &lt;strong&gt;the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/logs&lt;/code&gt; link on each worktree’s landing page goes directly to Grafana pre-filtered for that project.&lt;/strong&gt; Click the link from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supplyco-dev.localhost&lt;/code&gt;, you see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supplyco-dev&lt;/code&gt; logs. No query writing required.&lt;/p&gt;

&lt;p&gt;No thoughts, only logs.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;want&lt;/em&gt; to filter further, LogQL is there:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{project=&quot;supplyco-dev&quot;, service=&quot;api&quot;} |= &quot;error&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But most people never need it. They click the link, see their logs, find the error. The frontend dev doesn’t need to know what LogQL is. The cofounder definitely doesn’t. They click, they see, they fix, they leave.&lt;/p&gt;

&lt;p&gt;One dashboard, all worktrees, all services. No more “which container was that in?” or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker logs | grep&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;multi-worktree-isolation&quot;&gt;Multi-Worktree Isolation&lt;/h3&gt;

&lt;p&gt;The hard problem: multiple worktrees need to run simultaneously without stomping on each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database isolation:&lt;/strong&gt; Each worktree gets its own Postgres container with its own volume. No shared state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port isolation:&lt;/strong&gt; Services bind to internal Docker network ports, not host ports. Traefik handles external access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But what about GUI tools?&lt;/strong&gt; DataGrip, pgAdmin, TablePlus - they need a TCP port to connect. You can’t route Postgres through HTTP.&lt;/p&gt;

&lt;p&gt;For non-HTTP services, you have two real options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;TLS with SNI routing&lt;/strong&gt; - Traefik can route TCP connections based on the TLS server name. Each worktree gets &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supplyco-dev.localhost:5432&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supplyco-feature.localhost:5432&lt;/code&gt;, etc. Proper isolation, but requires TLS setup and your tools need to support it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Port stealing&lt;/strong&gt; - One worktree “claims” the standard port at a time. Simpler, works with any tool, but only one active worktree per port.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was lazy. I went with option 2:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# In worktree supplyco-dev&lt;/span&gt;
make expose-this-db
&lt;span class=&quot;c&quot;&gt;# Now localhost:5432 points to supplyco-dev&apos;s Postgres&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Switch to worktree supplyco-feature-x&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ../supplyco-feature-x
make expose-this-db
&lt;span class=&quot;c&quot;&gt;# Now localhost:5432 points to feature-x&apos;s Postgres&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Instant switching. DataGrip config stays the same (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:5432&lt;/code&gt;). Claude can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;psql&lt;/code&gt; without port gymnastics. It’s a socat container that forwards the port to whichever worktree ran the command last.&lt;/p&gt;

&lt;p&gt;Could I do TLS? Sure. Might I just add pgAdmin or CloudBeaver to the docker-compose and skip all this? Also yes. The port-stealing approach is “good enough for now” - the whole point is I can improve it later without anyone noticing.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;vpc-tunneling-the-rds-problem&quot;&gt;VPC Tunneling: The RDS Problem&lt;/h2&gt;

&lt;p&gt;Moving RDS into a private VPC was the right security call. But it broke local development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The old way (bad):&lt;/strong&gt; RDS in public subnet, security group allows your IP. Works until your IP changes, or you’re on coffee shop WiFi, or AWS throttles your connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The new way:&lt;/strong&gt; RDS in private subnet, bastion host in public subnet, tunnel through.&lt;/p&gt;

&lt;p&gt;But “tunnel through” meant:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Find the bastion instance ID&lt;/li&gt;
  &lt;li&gt;Get the RDS endpoint from… somewhere (Terraform outputs, technically - but I’ve banned the team from touching Terraform, and none of them have ever used it or entirely know what it does, which is correct and good)&lt;/li&gt;
  &lt;li&gt;Run an AWS SSM command with the right parameters&lt;/li&gt;
  &lt;li&gt;Hope you got the port right&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nobody could remember it. Nobody &lt;em&gt;should&lt;/em&gt; have to remember it. Scripts got written, lost, rewritten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; One script, multiple environments, automatic discovery:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;make db-forward-dev   &lt;span class=&quot;c&quot;&gt;# localhost:5433 → dev RDS&lt;/span&gt;
make db-forward-prod  &lt;span class=&quot;c&quot;&gt;# localhost:5434 → prod RDS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The script:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Gets bastion instance ID from Terraform outputs&lt;/li&gt;
  &lt;li&gt;Gets RDS endpoint from AWS Secrets Manager&lt;/li&gt;
  &lt;li&gt;Starts SSM port forwarding session&lt;/li&gt;
  &lt;li&gt;Outputs connection string for easy copy-paste&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Different local ports for dev vs prod means you can have both tunnels running simultaneously. Compare data between environments without reconnecting.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Connect to dev&lt;/span&gt;
make db-connect-dev
&lt;span class=&quot;c&quot;&gt;# Opens psql session directly&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Or just forward and use your GUI tool&lt;/span&gt;
make db-forward-dev
&lt;span class=&quot;c&quot;&gt;# &quot;Forwarding localhost:5433 → supplyco-dev-db.cluster-xxx.us-east-1.rds.amazonaws.com:5432&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &quot;Connection string: postgresql://app_user:xxx@localhost:5433/supplyco&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Claude can run these too. Production incident? Claude forwards the port, runs a query, reports back.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-makefile-one-command-for-everything&quot;&gt;The Makefile: One Command for Everything&lt;/h2&gt;

&lt;p&gt;The Makefile became the API for the dev environment. Every action has one command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Lifecycle&lt;/span&gt;
make docker-up              &lt;span class=&quot;c&quot;&gt;# Start everything&lt;/span&gt;
make docker-up &lt;span class=&quot;nv&quot;&gt;LITE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1       &lt;span class=&quot;c&quot;&gt;# Skip heavy services (saves RAM)&lt;/span&gt;
make docker-down            &lt;span class=&quot;c&quot;&gt;# Stop everything&lt;/span&gt;
make docker-down-v          &lt;span class=&quot;c&quot;&gt;# Stop and wipe data&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Logs&lt;/span&gt;
make docker-logs            &lt;span class=&quot;c&quot;&gt;# All services&lt;/span&gt;
make docker-logs-api        &lt;span class=&quot;c&quot;&gt;# Just FastAPI&lt;/span&gt;
make docker-logs-celery     &lt;span class=&quot;c&quot;&gt;# Just workers&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Database&lt;/span&gt;
make db-local-psql          &lt;span class=&quot;c&quot;&gt;# Connect to local Postgres&lt;/span&gt;
make db-local-migrate       &lt;span class=&quot;c&quot;&gt;# Run migrations&lt;/span&gt;
make db-local-reset         &lt;span class=&quot;c&quot;&gt;# Drop and recreate&lt;/span&gt;
make db-forward-dev         &lt;span class=&quot;c&quot;&gt;# Tunnel to dev RDS&lt;/span&gt;
make db-forward-prod        &lt;span class=&quot;c&quot;&gt;# Tunnel to prod RDS&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Quality&lt;/span&gt;
make lint                   &lt;span class=&quot;c&quot;&gt;# Fix linting issues&lt;/span&gt;
make check                  &lt;span class=&quot;c&quot;&gt;# Check without fixing (for CI)&lt;/span&gt;
make &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;                   &lt;span class=&quot;c&quot;&gt;# Run all tests&lt;/span&gt;
make &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ARGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;-k login&apos;&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# Run tests matching pattern&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Types &amp;amp; API&lt;/span&gt;
make api-types              &lt;span class=&quot;c&quot;&gt;# Regenerate TypeScript client from OpenAPI&lt;/span&gt;
make check-api-types        &lt;span class=&quot;c&quot;&gt;# Verify types are current&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Every target is documented with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;## comment&lt;/code&gt; so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make help&lt;/code&gt; produces a useful reference.&lt;/p&gt;

&lt;p&gt;No more “let me check the README” or “I think it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm run dev&lt;/code&gt; or maybe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn start&lt;/code&gt;?” The answer is always &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make &amp;lt;something&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;documentation-that-lives-with-the-code&quot;&gt;Documentation That Lives With the Code&lt;/h2&gt;

&lt;p&gt;READMEs rot. Wiki pages get lost. Notion docs go stale.&lt;/p&gt;

&lt;p&gt;We put everything in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docs/&lt;/code&gt; and serve it with MkDocs. And here’s the forcing function: &lt;strong&gt;CI blocks your PR unless you’ve updated the docs, or you explicitly add a “skip-docs-check” label.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No “I’ll document it later.” Later never comes. Either the docs get updated with the code, or you have to publicly declare “I’m skipping docs” on your PR. Shame-driven documentation.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docs/
├── architecture/
│   ├── overview.md           # System diagram
│   ├── domain.md             # Entity relationships
│   └── code-organization.md  # Where stuff goes
├── code-style/
│   ├── python.md             # Python conventions
│   ├── fastapi.md            # API patterns
│   ├── typescript.md         # Frontend conventions
│   └── terraform.md          # IaC patterns
├── guides/
│   ├── local-development.md  # This whole setup
│   ├── database.md           # SQLAlchemy, Alembic
│   ├── testing.md            # Test utilities
│   └── logging.md            # Logfire integration
└── operations/
    ├── deploys.md            # Release workflow
    └── incidents.md          # Runbook
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s accessible at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://{project}.localhost/docs&lt;/code&gt; - same hostname, different path.&lt;/p&gt;

&lt;p&gt;The CLAUDE.md file points here: “Before non-trivial work, read the relevant doc.” Claude actually does this. It’s remarkable how much better the code is when Claude reads the style guide first.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;making-it-agent-friendly&quot;&gt;Making It Agent-Friendly&lt;/h2&gt;

&lt;p&gt;Here’s the thing about Claude worktrees: they’re not just “another developer.” They’re parallel processes that need to be isolated, discoverable, and debuggable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Claude needs:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Discoverability&lt;/strong&gt;: Where’s the API? Where are the logs? What commands exist?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: Don’t step on other Claude instances&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Debugging tools&lt;/strong&gt;: When something fails, how to investigate&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Context&lt;/strong&gt;: What patterns does this codebase use?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What we built:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Landing page as entry point:&lt;/strong&gt; Claude can visit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://{project}.localhost/&lt;/code&gt; and see everything available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Makefile as API:&lt;/strong&gt; Every action is a documented make target. Claude runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make help&lt;/code&gt; and knows what’s possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logs accessible by URL:&lt;/strong&gt; Claude can check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://{project}.localhost/logs&lt;/code&gt; in a browser, or query Loki directly:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-sG&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;http://localhost:3100/loki/api/v1/query_range&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;--data-urlencode&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;query={project=&quot;supplyco-dev&quot;, service=&quot;api&quot;} |= &quot;error&quot;&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  | jq &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;.data.result[].values[][1]&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;CLAUDE.md with explicit guidance:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gu&quot;&gt;## Local Development&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Start: &lt;span class=&quot;sb&quot;&gt;`make docker-up`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; API docs: http://{project}.localhost/api/docs
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Logs: http://{project}.localhost/logs or &lt;span class=&quot;sb&quot;&gt;`make docker-logs-api`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Database: &lt;span class=&quot;sb&quot;&gt;`make db-local-psql`&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;## Before You Code&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Read docs/code-style/python.md for Python work
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Read docs/code-style/fastapi.md for API work
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Read docs/guides/testing.md before writing tests
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Hookify rules prevent common mistakes:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;# .claude/hookify-rules.local.md&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Don&apos;t import from supabase (we migrated away)
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Use uv, not pip
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Use pnpm, not npm
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Run make lint before committing
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Work-in-progress tracking:&lt;/strong&gt;
We use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.claudetext/&lt;/code&gt; for tracking what different Claude instances are working on. Convention: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ ]&lt;/code&gt; unclaimed, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[C]&lt;/code&gt; claimed by Claude, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[x]&lt;/code&gt; done. Prevents duplicate work.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-result&quot;&gt;The Result&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“How do I run the API?” (Slack, weekly)&lt;/li&gt;
  &lt;li&gt;“My migrations are conflicting with someone else’s” (constant)&lt;/li&gt;
  &lt;li&gt;“The tests pass locally but fail in CI” (environment drift)&lt;/li&gt;
  &lt;li&gt;“I can’t connect to the dev database” (VPC confusion)&lt;/li&gt;
  &lt;li&gt;Claude agents fighting over ports&lt;/li&gt;
  &lt;li&gt;Me: scared to touch infrastructure because of the support cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make docker-up&lt;/code&gt; and you’re running&lt;/li&gt;
  &lt;li&gt;Each worktree isolated by hostname&lt;/li&gt;
  &lt;li&gt;Logs aggregated and queryable from one place&lt;/li&gt;
  &lt;li&gt;Database tunnels are one command&lt;/li&gt;
  &lt;li&gt;Claude reads the docs, follows the patterns, doesn’t conflict with other agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For the frontend dev:&lt;/strong&gt; He runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make docker-up&lt;/code&gt;, goes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.localhost/frontend&lt;/code&gt;, never thinks about Docker. When something’s weird, he checks &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/logs&lt;/code&gt; in his browser. No Slack DM to me required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the cofounder:&lt;/strong&gt; Customer reports a bug. He pulls main, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make docker-up&lt;/code&gt;, reproduces it, fixes it, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make db-forward-dev&lt;/code&gt; to check prod data if needed, deploys. Back on a sales call in 30 minutes. Never asked me what port anything is on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For me:&lt;/strong&gt; I can improve infrastructure without fear. Last week I changed how we handle env vars. Nobody noticed. It just worked. That’s the goal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Claude:&lt;/strong&gt; Agents spin up isolated environments, check the landing page for URLs, query Loki for logs, read the docs before coding. They’re better at using the dev environment than most humans were before.&lt;/p&gt;

&lt;p&gt;The dev environment went from “source of constant interruptions” to “invisible infrastructure that just works.”&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-technical-details&quot;&gt;The Technical Details&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Traefik&lt;/strong&gt; - Reverse proxy with Docker provider, label-based routing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt; - Service orchestration per worktree&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Loki + Alloy&lt;/strong&gt; - Log aggregation with Docker label scraping&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Grafana&lt;/strong&gt; - Log visualization&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tempo&lt;/strong&gt; - Distributed tracing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MkDocs&lt;/strong&gt; - Documentation served locally&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AWS SSM&lt;/strong&gt; - Bastion tunneling for RDS access&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Makefile&lt;/strong&gt; - Unified command interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key files:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker-compose.dev.yml          # Main dev environment
docker/traefik/docker-compose.yml   # Shared Traefik + observability
docker/port-forwarder/          # Port claiming for GUI tools
scripts/port-forward-db.sh      # RDS tunneling
docs/                           # All documentation
Makefile                        # Command interface
CLAUDE.md                       # Agent context
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The magic:&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPOSE_PROJECT_NAME&lt;/code&gt; defaults to the directory name. Everything keys off that. Rename the directory, get a new isolated environment.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-i-learned&quot;&gt;What I Learned&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Dev environments are products.&lt;/strong&gt; Treat them like one. They need UX, documentation, and maintenance.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Discoverability beats documentation.&lt;/strong&gt; A landing page that links to everything is worth more than a README that explains everything.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Isolation is non-negotiable.&lt;/strong&gt; Especially with AI agents spinning up parallel environments. Design for multiple simultaneous instances from the start.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Observability isn’t optional.&lt;/strong&gt; You will need logs when things break. Make them easy to access before things break.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;One command per action.&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make docker-up&lt;/code&gt; is infinitely better than “run this, then that, then set this env var, then…”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Agents need the same things humans need&lt;/strong&gt; - just more explicitly documented. CLAUDE.md isn’t extra work, it’s documentation you should have written anyway.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;If your dev environment is in the “47 Makefile targets” phase:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Add a reverse proxy.&lt;/strong&gt; Traefik with Docker labels is ~50 lines of config. Suddenly you have URLs instead of ports.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Add a landing page.&lt;/strong&gt; One HTML file that links to all your services. Put it at the root route.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Aggregate your logs.&lt;/strong&gt; Loki + Alloy is free and runs locally. One dashboard instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker logs&lt;/code&gt; across 10 terminals.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Document commands, not concepts.&lt;/strong&gt; Your Makefile should be the entire interface. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make help&lt;/code&gt; should answer most questions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Write CLAUDE.md.&lt;/strong&gt; Not because you’re using AI, but because explaining your environment to an agent forces you to make it logical.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best dev environment is one that makes the next person (or the next Claude) productive immediately. Everything else is just complexity.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Our setup is specific to our stack (Python/FastAPI/React/AWS), but the patterns generalize. The goal is: clone repo, run one command, be productive. If your env requires more than that, you have work to do.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How I Used AI to Outsource My Executive Function</title>
   <link href="https://w.laudiacay.cool/2026/01/02/ai-executive-function.html"/>
   <updated>2026-01-02T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2026/01/02/ai-executive-function</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Building a personal operating system with Claude Code when your brain fights you&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-problem-context-scatter-as-a-founder&quot;&gt;The Problem: Context Scatter as a Founder&lt;/h2&gt;

&lt;p&gt;I have ADHD. I run a company. I also have a body that needs PT exercises, meal planning, and regular gym sessions. Every morning I’d wake up to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Linear inbox with issues&lt;/li&gt;
  &lt;li&gt;Slack with @mentions and DMs&lt;/li&gt;
  &lt;li&gt;GitHub with PRs needing review&lt;/li&gt;
  &lt;li&gt;Email (personal AND work)&lt;/li&gt;
  &lt;li&gt;TickTick with half-finished todo items&lt;/li&gt;
  &lt;li&gt;A nutrition plan I’d inevitably forget&lt;/li&gt;
  &lt;li&gt;A workout routine I’d modify based on which body part hurt that day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cognitive load of &lt;em&gt;just figuring out what to do&lt;/em&gt; was exhausting before I’d done anything. Context switching between 8+ apps, each with their own notification system, each requiring different mental models. For someone with executive function challenges, this is death by a thousand cuts.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-insight-what-if-ai-could-be-my-prefrontal-cortex&quot;&gt;The Insight: What If AI Could Be My Prefrontal Cortex?&lt;/h2&gt;

&lt;p&gt;I started using Claude Code for work stuff - code reviews, debugging, writing features. But then I noticed something: Claude was really good at structured decision-making. The exact thing my brain sucks at.&lt;/p&gt;

&lt;p&gt;What if I could program Claude to:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Aggregate&lt;/strong&gt; all my contexts into one place&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enforce&lt;/strong&gt; good habits through methodology (GTD)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automate&lt;/strong&gt; the boring stuff entirely&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Guide&lt;/strong&gt; me through decisions I’d otherwise avoid&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-system-i-built&quot;&gt;The System I Built&lt;/h2&gt;

&lt;h3 id=&quot;morning---the-daily-aggregator&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/morning&lt;/code&gt; - The Daily Aggregator&lt;/h3&gt;

&lt;p&gt;Every morning, I type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/morning&lt;/code&gt; and Claude:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Opens my Linear, Graphite, and Slack dashboards&lt;/li&gt;
  &lt;li&gt;Asks me to paste whatever I see (Claude can read screenshots!)&lt;/li&gt;
  &lt;li&gt;Fetches via API:
    &lt;ul&gt;
      &lt;li&gt;GitHub PRs needing my review&lt;/li&gt;
      &lt;li&gt;My PRs that are stuck/approved/need fixes&lt;/li&gt;
      &lt;li&gt;Linear issues assigned to me&lt;/li&gt;
      &lt;li&gt;Email counts from both accounts&lt;/li&gt;
      &lt;li&gt;TickTick tasks due today/overdue&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Presents a unified dashboard&lt;/li&gt;
  &lt;li&gt;Walks me through building today’s plan interactively&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## Morning Dashboard

### PRs Needing Your Review (3)
- supplyco#1739 - &quot;Add RLS policies&quot; by @vlad
- supplyco#1725 - &quot;Fix auth flow&quot; by @jannik (CHANGES_REQUESTED by you)

### Your PRs - Status Check
- #1698 &quot;Metrics dashboard&quot; - APPROVED ← merge this?
- #1702 &quot;API refactor&quot; - waiting on reviewers

### Linear Issues (5)
- [SUP-1542] Blocked: dependency on Jannik&apos;s PR
- [SUP-1589] Due today: write migration

### Email: Personal 12, Work 8
### TickTick: 4 due today, 2 overdue
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then it asks: “What should go on today’s plan?” and creates TickTick tasks with proper due dates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key insight&lt;/strong&gt;: I don’t have to context-switch. I don’t have to remember which app has what. I just answer questions.&lt;/p&gt;

&lt;h3 id=&quot;the-hybrid-approach-dashboards-that-wont-automate&quot;&gt;The Hybrid Approach: Dashboards That Won’t Automate&lt;/h3&gt;

&lt;p&gt;Here’s the thing: not everything has a nice API. Linear has an MCP, but it’s clunky for inbox-style browsing. Slack’s API doesn’t capture the gestalt of “what’s blowing up right now.” Graphite (our PR tool) has no API at all. LinkedIn DMs? Forget it.&lt;/p&gt;

&lt;p&gt;So I built a hybrid system. Claude runs:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;open &lt;span class=&quot;s2&quot;&gt;&quot;https://linear.app/mycompany/inbox&quot;&lt;/span&gt;
open &lt;span class=&quot;s2&quot;&gt;&quot;https://app.graphite.dev/#needs-your-review&quot;&lt;/span&gt;
open &lt;span class=&quot;s2&quot;&gt;&quot;https://app.slack.com/client&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Three browser tabs pop up. Claude then asks me to paste what I see - and crucially, &lt;strong&gt;Claude can read screenshots&lt;/strong&gt;. So I:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Cmd+Shift+4 to screenshot the Linear inbox&lt;/li&gt;
  &lt;li&gt;Paste it into the terminal&lt;/li&gt;
  &lt;li&gt;Claude parses it: “I see 5 issues assigned to you, 2 are marked urgent…”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or I just Cmd+A, Cmd+C the text and paste it. Either works.&lt;/p&gt;

&lt;p&gt;I’ve also gotten automated scrolling screenshots working with Apple’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screencapture&lt;/code&gt; and osascript - it can capture an entire scrollable page. I occasionally use these for long Slack threads or Linear backlogs. Next step is programming those into the workflows so Claude can just grab them automatically.&lt;/p&gt;

&lt;p&gt;The key is: &lt;strong&gt;my focus immediately returns to the terminal.&lt;/strong&gt; The browser tabs are open, but I’m not there. I grabbed what I needed and came back. Claude becomes the home base that I always return to after quick excursions into distracting apps.&lt;/p&gt;

&lt;p&gt;This matters because my failure mode isn’t “I don’t check Slack.” It’s “I check Slack and then it’s 2 hours later.” The open → grab → return flow keeps the terminal as my anchor.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;why-i-could-never-do-gtd-before-and-why-claude-changed-that&quot;&gt;Why I Could Never Do GTD Before (And Why Claude Changed That)&lt;/h3&gt;

&lt;p&gt;I’ve read &lt;em&gt;Getting Things Done&lt;/em&gt; three times. I’ve tried OmniFocus, Things, Todoist, Notion, paper systems. I understand the methodology intellectually. Inbox zero, weekly reviews, next actions, contexts - I get it.&lt;/p&gt;

&lt;p&gt;I just couldn’t &lt;em&gt;do&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;The problem with GTD for ADHD brains is that it requires sustained executive function at exactly the moment you have none. You’re supposed to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Look at your inbox&lt;/li&gt;
  &lt;li&gt;Pick ONE item&lt;/li&gt;
  &lt;li&gt;Ask “is it actionable?”&lt;/li&gt;
  &lt;li&gt;If yes, ask “what’s the next action?”&lt;/li&gt;
  &lt;li&gt;Route it appropriately&lt;/li&gt;
  &lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple, right? Except my brain does this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Look at inbox&lt;/li&gt;
  &lt;li&gt;See 47 items&lt;/li&gt;
  &lt;li&gt;Feel overwhelmed&lt;/li&gt;
  &lt;li&gt;Notice an interesting link&lt;/li&gt;
  &lt;li&gt;Open 12 browser tabs&lt;/li&gt;
  &lt;li&gt;Forget I was processing inbox&lt;/li&gt;
  &lt;li&gt;Add “process inbox” to inbox&lt;/li&gt;
  &lt;li&gt;Close laptop&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The methodology isn’t the problem. The &lt;em&gt;execution&lt;/em&gt; is the problem.&lt;/p&gt;

&lt;h3 id=&quot;askuserquestion-as-adhd-medication&quot;&gt;AskUserQuestion as ADHD Medication&lt;/h3&gt;

&lt;p&gt;Here’s what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/gtd-process&lt;/code&gt; actually looks like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Claude: Processing inbox item 1 of 23:
&quot;interesting article about distributed systems&quot;

Is this actionable?
○ Yes - there&apos;s something I need to DO
○ No - it&apos;s reference/inspiration
○ Trash - I don&apos;t need this

Me: [clicks &quot;No&quot;]

Claude: Where should this go?
○ Someday/Maybe - might read later
○ Reference - save with a tag
○ Trash - actually I don&apos;t need it

Me: [clicks &quot;Trash&quot;]

Claude: ✓ Deleted.

Processing item 2 of 23:
&quot;Call dentist&quot;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice what’s happening:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;One item at a time.&lt;/strong&gt; I literally cannot see item 3 until I’ve decided on item 2.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Forced binary choices.&lt;/strong&gt; Not “what do you want to do?” but “pick A, B, or C.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Claude proposes, I dispose.&lt;/strong&gt; The cognitive load of &lt;em&gt;generating options&lt;/em&gt; is removed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Progress is visible.&lt;/strong&gt; “Item 7 of 23” creates momentum.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No escape.&lt;/strong&gt; I can’t open a new tab because I’m in the terminal and Claude is waiting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the external structure my brain lacks internally.&lt;/p&gt;

&lt;h3 id=&quot;the-brainrotted-zoomer-interface&quot;&gt;The “Brainrotted Zoomer” Interface&lt;/h3&gt;

&lt;p&gt;I call it the “brainrotted zoomer” interface because it’s designed for someone with the attention span of a TikTok scroll:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Micro-decisions only.&lt;/strong&gt; Never “plan your week.” Always “is THIS one thing actionable, yes or no?”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Immediate feedback.&lt;/strong&gt; Task moved, checkmark shown, next item appears.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No dead ends.&lt;/strong&gt; If I say “unsure,” Claude asks a clarifying question. I’m never stuck staring at something.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Suggested actions.&lt;/strong&gt; Instead of “what’s the next action?” Claude says:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;What&apos;s the next physical action? I suggest:
○ &quot;Call Dr. Smith to schedule appointment&quot;
○ &quot;Text Sarah about Saturday plans&quot;
○ &quot;Research best options online&quot;
○ Other - I&apos;ll type it
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I can just tap an option. The verb is already there. The specificity is already there. I’m not generating, I’m selecting.&lt;/p&gt;

&lt;h3 id=&quot;why-this-finally-works&quot;&gt;Why This Finally Works&lt;/h3&gt;

&lt;p&gt;Traditional productivity systems assume you can:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Hold context in working memory&lt;/li&gt;
  &lt;li&gt;Generate options from scratch&lt;/li&gt;
  &lt;li&gt;Maintain focus through a list&lt;/li&gt;
  &lt;li&gt;Self-direct without external structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ADHD means I can’t do any of that reliably. But I &lt;em&gt;can&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Answer a direct question&lt;/li&gt;
  &lt;li&gt;Pick from multiple choice&lt;/li&gt;
  &lt;li&gt;Follow along when someone else leads&lt;/li&gt;
  &lt;li&gt;Stay engaged when there’s immediate feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude becomes the external executive function. It holds the context (“you’re on item 7 of 23, you’ve trashed 3, moved 2 to someday”). It generates the options (“here are three possible next actions”). It maintains focus (“okay, now here’s item 8”). It provides structure (“is this actionable, yes or no?”).&lt;/p&gt;

&lt;p&gt;I’m not doing GTD. Claude is doing GTD &lt;em&gt;to&lt;/em&gt; me. And that’s why it finally works.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;inbox---email-triage-without-the-dread&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/inbox&lt;/code&gt; - Email Triage Without the Dread&lt;/h3&gt;

&lt;p&gt;Same principle applied to email:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Claude: Email 3 of 18:
From: eric@supplier.com
Subject: Re: MacBook order status
Received: 2 days ago
Preview: &quot;Hey, following up on the laptop order...&quot;

What would you like to do?
○ Tell me more - show full email
○ Archive - I&apos;ve handled this
○ Create todo - need to respond/act
○ Draft reply - help me write back
○ Skip - deal with later
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If I pick “Tell me more,” Claude fetches the full email, summarizes it, and asks again. If I pick “Create todo,” it asks for a due date and creates a TickTick task like “Reply to Eric about MacBook order” with proper GTD formatting.&lt;/p&gt;

&lt;p&gt;The inbox goes from “264 unread anxiety pile” to “answer 18 questions and you’re done.”&lt;/p&gt;

&lt;h3 id=&quot;the-recursive-loop-everything-flows-back&quot;&gt;The Recursive Loop: Everything Flows Back&lt;/h3&gt;

&lt;p&gt;Here’s where it gets elegant: &lt;strong&gt;the system feeds itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When I process email with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/inbox&lt;/code&gt; and choose “Create todo,” that task goes into TickTick. Later, when I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/gtd-process&lt;/code&gt;, that same task comes back through Claude for processing. If it’s vague (“deal with MacBook situation”), Claude helps me sharpen it (“Email Eric confirming delivery date”).&lt;/p&gt;

&lt;p&gt;If it needs research, I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/research-task&lt;/code&gt; on it - which produces &lt;em&gt;more&lt;/em&gt; tasks that flow back into TickTick. If those tasks produce emails, those emails get processed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/inbox&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Email inbox → /inbox → TickTick task
                            ↓
                      /gtd-process → sharpen task
                            ↓
                      /research-task → research + new tasks
                            ↓
                      TickTick → more tasks for /gtd-process
                            ↓
                      Action → sends email → response arrives
                            ↓
                      Email inbox → /inbox → ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Everything flows through Claude. Claude is the processing layer between all my inboxes. The recursive nature means nothing gets lost - it just keeps cycling through until it’s either done or explicitly deferred to Someday/Maybe.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;research-task---when-you-dont-know-what-to-do&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/research-task&lt;/code&gt; - When You Don’t Know What To Do&lt;/h3&gt;

&lt;p&gt;Some tasks sit in my Next Actions list because I don’t actually know how to do them. “Save money on Cytopoint” - my dog needs this expensive medication. I know I should research alternatives but… that’s vague and overwhelming.&lt;/p&gt;

&lt;p&gt;So I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/research-task &quot;Save money on Cytopoint&quot;&lt;/code&gt; and Claude launches into research mode:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Claude: I&apos;ll help you research cheaper Cytopoint options. First, some questions:

What&apos;s your current situation?
○ Getting it from the vet directly
○ Using Chewy/online pharmacy
○ Not sure of current price
○ Other

Me: [clicks &quot;Getting it from vet directly&quot;]

Claude: What&apos;s your dog&apos;s weight/dosage?

Me: 40lb, monthly injection

Claude: Got it. Let me research options...
[web searches, fetches pharmacy pages, reads rebate programs]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ten minutes later, Claude produces a memo:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## Research: Cheaper Cytopoint Options

**Current cost:** ~$80-150/month at vet

**Findings:**

1. **Costco Pharmacy** - $45-65 for same injection
   - Has pet Rx program, no membership needed for pharmacy
   - Delivers to home
   - Need vet to send prescription

2. **Zoetis Rewards** - Manufacturer rebate program
   - $30 back after 2nd injection
   - $50 back after 4th injection
   - Stackable with pharmacy savings

3. **Librela** - Newer alternative medication
   - Similar mechanism, may work for some dogs
   - Slightly different side effect profile
   - Worth discussing with vet

**Recommendation:** Switch to Costco pharmacy + enroll in Zoetis Rewards. Ask vet about Librela as backup option.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then Claude asks what to do with this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;How would you like to proceed?
○ Create next-action tasks (I&apos;ll schedule the calls/emails)
○ Make original task actionable (update with specific next step)
○ Just the memo - I&apos;ll handle manually
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I pick “Create next-action tasks” and Claude creates:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Call Costco pharmacy about pet Rx delivery” - due tomorrow&lt;/li&gt;
  &lt;li&gt;“Email vet requesting Cytopoint prescription to Costco” - due tomorrow&lt;/li&gt;
  &lt;li&gt;“Sign up for Zoetis Rewards rebate program” - due today (quick)&lt;/li&gt;
  &lt;li&gt;“Ask vet about Librela at next appointment” - due next month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vague “save money” task becomes four concrete actions with verbs and dates. The research is done. The decisions are made. I just execute.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;hevy---ai-built-pt-routines&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/hevy&lt;/code&gt; - AI-Built PT Routines&lt;/h3&gt;

&lt;p&gt;This is where it gets weird and cool.&lt;/p&gt;

&lt;p&gt;I had chronic pain issues. I’d done PT but couldn’t keep track of which exercises to do. So I started having conversations with Claude about my symptoms:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“I have forward head posture and my right hip is always tight. Also my feet collapse inward when I squat.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude would research the biomechanics, suggest exercises, and explain the mechanism. Then I’d say “add that to my workout routine” and Claude would call the Hevy API to update my gym app directly.&lt;/p&gt;

&lt;p&gt;My current routines have exercises like:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Chin tucks&lt;/strong&gt; and &lt;strong&gt;wall slides&lt;/strong&gt; (forward head posture)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Face pulls&lt;/strong&gt; with notes: “Pull to face, elbows HIGH. Squeeze rear delts.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Short foot&lt;/strong&gt; with notes: “Shorten foot WITHOUT curling toes. Pull ball toward heel, create dome. Toes LONG/relaxed.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dead bugs&lt;/strong&gt; with notes: “RIB CONTROL: Exhale fully, ribs drop to floor. Low back FLAT.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tibialis raises&lt;/strong&gt; with notes: “Back to wall, feet 12in out. Lift toes toward shins. Pause 1s at top, 3s down.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The form cues are embedded in my workout app.&lt;/strong&gt; When I’m at the gym, I just open Hevy, and the routine Claude and I debugged together is right there with instructions. No memory required. No “what was that exercise my PT showed me?”&lt;/p&gt;

&lt;p&gt;I ran diagnostic conversations like:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“My right shoulder clicks when I raise my arm overhead” → added specific rotator cuff work&lt;/li&gt;
  &lt;li&gt;“I can’t get into a deep squat without my heels rising” → added ankle mobility (knee-to-wall) and calf stretches&lt;/li&gt;
  &lt;li&gt;“My lower back hurts after sitting” → added hip flexor stretches, glute activation, core anti-extension work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each conversation produced updates to my actual workout routine. The gym became a place to execute, not to think.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;aws-lambda--ssm-claude-1password&quot;&gt;AWS Lambda + SSM: “Claude 1Password”&lt;/h3&gt;

&lt;p&gt;My YNAB (budgeting app) was always messy. Amazon transactions would say “AMAZON.COM” with no detail about what I bought. I’d have to cross-reference email receipts manually to remember if that $47.23 was cat food or impulse purchases.&lt;/p&gt;

&lt;p&gt;So I built a Lambda that runs every hour:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Fetches Amazon/Apple receipt emails from Gmail&lt;/li&gt;
  &lt;li&gt;Parses item names and prices from the HTML&lt;/li&gt;
  &lt;li&gt;Matches to YNAB transactions by amount and date (±5 days tolerance)&lt;/li&gt;
  &lt;li&gt;Uses Claude Haiku via AWS Bedrock to shorten long product names (40+ chars → 2-4 words)&lt;/li&gt;
  &lt;li&gt;Updates the YNAB memo field automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now my transactions auto-label themselves:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Amazon: Cat Food 15lb ($24.99), Protein Bars 12ct ($18.99), +2 more
Apple: Claude Pro Subscription ($20.00)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All credentials live in AWS SSM Parameter Store. I call it “Claude 1Password” - Claude can fetch any API key it needs with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws ssm get-parameter&lt;/code&gt;, and I never have to paste secrets into chat or worry about them leaking.&lt;/p&gt;

&lt;p&gt;The Terraform for this is like 100 lines. EventBridge triggers hourly, Lambda runs, my budget stays accurate without me thinking about it.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;grocery-lists--nutrition-autopilot&quot;&gt;Grocery Lists + Nutrition Autopilot&lt;/h3&gt;

&lt;p&gt;I used to meal plan by staring at an empty document, getting overwhelmed, and ordering DoorDash.&lt;/p&gt;

&lt;p&gt;Now:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Tell Claude my macro targets and dietary restrictions&lt;/li&gt;
  &lt;li&gt;Claude suggests a week of meals&lt;/li&gt;
  &lt;li&gt;I pick the ones that sound good&lt;/li&gt;
  &lt;li&gt;Claude generates a grocery list organized by store section&lt;/li&gt;
  &lt;li&gt;I buy roughly the same stuff every week with minor variations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The decision fatigue is gone. I’m not standing in the grocery store wondering what to buy. I have a list. The list produces meals. The meals hit my macros.&lt;/p&gt;

&lt;p&gt;Nutrition is on autopilot. I follow the system.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;the-expanding-frontier&quot;&gt;The Expanding Frontier&lt;/h3&gt;

&lt;p&gt;The system keeps growing because it’s self-reinforcing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning makeup:&lt;/strong&gt; “What order do I apply these products? What’s wrong with my technique based on this photo?” Claude can look at selfies and give specific feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fashion:&lt;/strong&gt; “I’m going to [X event], I own [Y items], what works together?” Outfit planning without the paralysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Company planning:&lt;/strong&gt; Strategic roadmaps, investor update drafts, hiring rubrics, competitive analysis. Work stuff, but guided instead of blank-page.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-snowball-effect&quot;&gt;The Snowball Effect&lt;/h2&gt;

&lt;p&gt;Here’s what nobody tells you about integrating AI into your life: &lt;strong&gt;it compounds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The more context Claude has about:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;My work projects (Linear, GitHub, codebase)&lt;/li&gt;
  &lt;li&gt;My habits (TickTick patterns, what I defer vs complete)&lt;/li&gt;
  &lt;li&gt;My body (PT history, what’s worked)&lt;/li&gt;
  &lt;li&gt;My preferences (past decisions, communication style)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The better its suggestions become. Claude starts to know that I always defer dentist appointments, so it asks “is this actually happening or should we Someday/Maybe it?” Claude knows I respond well to morning workouts, so it doesn’t suggest evening gym sessions.&lt;/p&gt;

&lt;p&gt;It’s like having a chief of staff who’s read every email, attended every meeting, and remembers everything. Each new integration makes the whole system smarter.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-autopilot-actually-means&quot;&gt;What “Autopilot” Actually Means&lt;/h2&gt;

&lt;p&gt;My daily overhead is now:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Morning&lt;/strong&gt;: Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/morning&lt;/code&gt;, answer questions for 5-10 minutes, get a plan&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Gym&lt;/strong&gt;: Open Hevy, follow the routine Claude and I designed. Every exercise has form cues.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Email&lt;/strong&gt;: Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/inbox&lt;/code&gt; when I have energy, archive/todo/skip through them&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tasks&lt;/strong&gt;: Work from my TickTick “Today” view - everything already has verbs and due dates&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Meals&lt;/strong&gt;: Follow the grocery list, cook the planned meals&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The stuff I used to burn executive function on - &lt;em&gt;figuring out what to do, remembering how to do exercises correctly, deciding what to eat, enriching budget transactions, processing email&lt;/em&gt; - just happens.&lt;/p&gt;

&lt;p&gt;My job is now to:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Show up at the gym&lt;/li&gt;
  &lt;li&gt;Eat what’s on the list&lt;/li&gt;
  &lt;li&gt;Work through the tasks Claude helped me prioritize&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The meta-work is gone. The actual work remains.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-technical-stack&quot;&gt;The Technical Stack&lt;/h2&gt;

&lt;p&gt;For the curious:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Custom slash commands defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.claude/commands/*.md&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Each command is a workflow written in markdown that Claude follows&lt;/li&gt;
  &lt;li&gt;MCP (Model Context Protocol) servers for Hevy, Slack, Linear&lt;/li&gt;
  &lt;li&gt;Python scripts for Gmail, TickTick (Claude calls via Bash)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS Infrastructure:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Lambda (container-based) for background jobs&lt;/li&gt;
  &lt;li&gt;ECR for container images&lt;/li&gt;
  &lt;li&gt;SSM Parameter Store for all credentials (“Claude 1Password”)&lt;/li&gt;
  &lt;li&gt;EventBridge for hourly scheduling&lt;/li&gt;
  &lt;li&gt;Bedrock (Claude Haiku) for text processing in Lambda&lt;/li&gt;
  &lt;li&gt;SNS + ntfy.sh for mobile alerts&lt;/li&gt;
  &lt;li&gt;CloudWatch for logs and metrics&lt;/li&gt;
  &lt;li&gt;Terraform for infrastructure-as-code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integrations:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Gmail API (personal + work accounts)&lt;/li&gt;
  &lt;li&gt;YNAB API (budgeting)&lt;/li&gt;
  &lt;li&gt;TickTick API (tasks)&lt;/li&gt;
  &lt;li&gt;Linear API (issues)&lt;/li&gt;
  &lt;li&gt;GitHub API (PRs)&lt;/li&gt;
  &lt;li&gt;Hevy API (workouts)&lt;/li&gt;
  &lt;li&gt;Slack API (messages)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The slash commands are just markdown files that define a workflow. Claude reads them and follows the steps. It’s programming by writing English that explains what you want.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-this-means&quot;&gt;What This Means&lt;/h2&gt;

&lt;p&gt;I’m not sure I’m “using AI” anymore in the way most people mean. Claude isn’t a tool I pick up to do a task. It’s the interface through which I interact with my own life systems.&lt;/p&gt;

&lt;p&gt;The distinction matters because it changes the frame from “AI can help with X” to “what would it look like if AI handled all the glue work?”&lt;/p&gt;

&lt;p&gt;For someone with ADHD, the glue work - context switching, remembering, prioritizing, maintaining systems, generating options, sustaining focus - is often harder than the actual work. The actual work is fine. It’s everything around the work that kills me.&lt;/p&gt;

&lt;p&gt;Now I have a system that:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Aggregates&lt;/strong&gt; instead of scatters&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enforces&lt;/strong&gt; methodology instead of hoping I remember&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automates&lt;/strong&gt; the boring parts entirely&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Guides&lt;/strong&gt; me through decisions with proposed options&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Remembers&lt;/strong&gt; everything I forget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I just have to show up and answer questions.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;If you want to build something like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Start with one pain point.&lt;/strong&gt; Mine was the morning chaos. What’s yours?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Write a Claude command for it.&lt;/strong&gt; Just a markdown file explaining the workflow you wish existed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Add integrations as needed.&lt;/strong&gt; MCP servers, Python scripts, API calls.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Notice what else is annoying.&lt;/strong&gt; Build a command for that too.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Let it compound.&lt;/strong&gt; Each new piece makes the whole system more useful.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The system grows from there. You’re not building an app. You’re programming a chief of staff in English.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;If this resonates and you want to see the actual code/commands, I might open-source the setup. Let me know.&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Token: Considered Harmful</title>
   <link href="https://w.laudiacay.cool/2024/05/23/token-considered-harmful.html"/>
   <updated>2024-05-23T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/05/23/token-considered-harmful</id>
   <content type="html">&lt;p&gt;&lt;em&gt;You’ll be pleased to know that I left crypto shortly after writing this essay.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Notes from inside the machine.&lt;/p&gt;

&lt;p&gt;I’ll probably do plenty of ragging on projects I’m familiar with. It doesn’t mean they’re exceptionally bad, or that other projects are exceptionally good, just that I am more familiar with how things went down.&lt;/p&gt;
&lt;h2 id=&quot;hot-take-ponzi-schemes-can-be-beautiful&quot;&gt;Hot take: Ponzi schemes can be beautiful&lt;/h2&gt;
&lt;p&gt;Economic bubbles have historically been engines of real progress. The dot-com bust left us with an abundance of fiber optic cable that powered the next decade of internet growth. The Roaring Twenties built infrastructure that served America for generations. Speculative excess, channeled well, can fund things that rational capital allocation never would.&lt;/p&gt;

&lt;p&gt;You have to give proof-of-work and proof-of-stake L1 chains their due credit: the trick startups do, where they hand out equity to the long-suffering early employees, is brilliantly repurposed to direct the long-term reward towards the exact action needed to create and secure the chain. One of the coolest things about our industry is how aggressively we blur the lines of compensable work, although we’ve since proceeded to beat the concept to death several times over.&lt;/p&gt;

&lt;p&gt;Startups have long paid their early employees in equity or options- in exchange for a high performer’s opportunity cost elsewhere, they get a piece of the future value of the venture, which encourages them to fight for their team to win. Startups have also often subsidized early customers’ costs with investor money, hoping that they will build sufficient network effects before the money runs out and stick the landing into profitability. Businesses frequently craft creative compensation packages for executives and salespeople to induce them to achieve certain goals. Bringing game theory in to accomplish something cool isn’t new. Using it to convince selfish humans to collaborate and scale something beyond their wildest dreams is also not new. What is new is how creative we got with it and how we automated it to remove the bureaucracy.&lt;/p&gt;

&lt;p&gt;Smart contracts have built novel ways to bring people together, making markets, investing in startups, running network nodes, attempting to create digital museums, and more. They’re just helpless dead code until they induce humans to execute and interact with them. What animates them is when programmers weave intricate systems of monetary forces into code and data to induce people to interact with the system and accomplish interesting things cooperatively without any mediating entity. Successful examples of this include millions of ASICs executing SHA256 until they find a small enough output, adding transactions into blocks and executing them, liquidating bad debt, connecting hard drives to a network to ostensibly store files, or building an intricate crypto-backed dollar-pegged stablecoin. It’s insane; it feels like magic that you can literally write some text to summon millions of dollars and thousands of people with your computer.&lt;/p&gt;

&lt;p&gt;Of course, legal codes, contracts, and inspiring speeches can also muster and direct outsize resources like this. But I’ve never seen something so fast and automated. A permissionless piece of code where legal contracts, security issuance, citizenship concerns, KYC, and all the other accumulated bureaucratic kruft are thrown out in exchange for “execute this computation, this other number will increase, and you can trade that number for dollars” is &lt;em&gt;cool&lt;/em&gt;. It is limited in that it is sort of difficult to incentivize things that cannot be directly validated by a Turing machine, but oracle technology is good and getting better.&lt;/p&gt;

&lt;p&gt;It’s awesome. You can summon up massive swarms of organized humans and machines with a text file. You can even get them to do interesting and useful things if you’re careful.&lt;/p&gt;
&lt;h2 id=&quot;misfiring-the-money-cannon&quot;&gt;Misfiring the Money Cannon&lt;/h2&gt;
&lt;p&gt;That “careful” bit is quite load-bearing. The first fall from token grace is when people do the classic government trick and incentivize something very similar to, but not exactly, the goal. Lots of people like to quote Stafford Beer in saying that “the purpose of a system is what it does”, and this gets poetically illustrated when the (public) incentives on the (public) protocols are released into the wild, everyone in the project behaves mostly in good faith, everyone outside the project behaves rationally, and they all proceed to accomplish something hilariously orthogonal to the stated goals of the project.&lt;/p&gt;

&lt;p&gt;My favorite examples of this are BitTensor and Filecoin, with their “innovations” of useful proofs of work (UPoW). BitTensor attempts to link a computational proof of work to useful machine learning inferences, while Filecoin attempts to link useful data storage to hard drive consumption as their proof of work. In practice, both of these are not useful. It is very difficult (one might even say “obviously paradoxical”) to build a resource-intensive &lt;a href=&quot;https://en.wikipedia.org/wiki/Potlatch&quot;&gt;potlatch&lt;/a&gt; that the participants make to secure the chain as a credible and costly signal, which also serves as a competitively-priced computational commodity (without taking the “pump” side of the pump-and-dump as permanent). In the end, you waste the content of the potlatch regardless of whether you choose UPoW or PoW, but you add the waste of years of your team’s time trying to bring your unsellable UPoW “resources” to market. Instead of salvaging some waste, you waste inestimably more.&lt;/p&gt;

&lt;p&gt;(Note that we found a very nice solution to the conundrum: the potlatch can choose to sacrifice financial optionality, from which we get the more resource-efficient (although potentially with cyclical risk issues) proof-of-stake.)&lt;/p&gt;

&lt;p&gt;My favorite ill-designed incentive is not alone; the industry has far more failed evolutions than successful ones. Again and again, we see token inflation going to airdrop farming, fake “users” who are farming for tokens instead of using the product (see: crypto games like Axie Infinity), alt-L1 “usage”, ecosystem protocol deployment of unusable “apps”, and the ridiculous economic situations we invariably discover under the promising metrics when DePINs scale.&lt;/p&gt;

&lt;p&gt;It’s not a fun trap to find yourself in: you cast your spell when you deploy your ecosystem, and the value accordingly floods in. Suddenly, every move has sky-high stakes for your protocol and token price. Changing the topology of the financial reality you have now created is a high-friction process, especially if you (like most of web3) are sticking to democratic governance ideals that prevent you from rapidly iterating on your prototypes like a startup ought to be. Unfortunately, it may be hard to break away from this and iterate freely, as your stakeholders have often sunk significant amounts of capital into their interactions with your incentive scheme. You’ve become beholden to them, at least reputationally, if not legally.&lt;/p&gt;

&lt;p&gt;Another common failure is a mismatch of the incentives’ velocity to the project’s goals. Most projects’ incentives use a bit of ponzinomics, or rewarding early contributors with outsize token shares in order to reward them for taking a risk. This is to induce the network to grow to a size where you start getting nice valuable network effects. Uber did this for years, by softening both sides of the market with venture capital money.&lt;/p&gt;

&lt;p&gt;The most common failure mode here is shooting off all the bonus incentives for bootstrapping before the network reaches a steady state. I believe this is the way that Bitcoin will eventually die. Ethereum seems to be doing better with getting sufficient inbound gas fees to feed the validators, at least as long as there are people attempting to build apps atop it. (but my previous post discusses why this might not last either)&lt;/p&gt;

&lt;p&gt;In my opinion, judiciously used ponzinomics are fantastic jet fuel. Properly built, they’re the financial energy that converts ideas to reality. Clumsy, naive, or predatory ponzinomics are the problematic side of tokens. Now, we’ll start to discuss the more predatory ones.&lt;/p&gt;
&lt;h2 id=&quot;vesting-and-trying-to-get-in-early&quot;&gt;Vesting and “trying to get in early”&lt;/h2&gt;

&lt;p&gt;A core tension is the one between the difficulty of the things we’re trying to accomplish and the perverse timelines we’ve set for ourselves. Most things that are sufficiently cool to excite a community to participate in the incentive scheme, and most things with sufficient market to draw venture capital investment, are extremely ambitious. Ambitious things are hard. Ambitious things take time. Building something massive, as a key person or founder, may take a decade of hard work, which is not even reflected in standard four-year startup vesting. Contributing substantially to a product as an employee takes years, which is probably reflected well in standard startup vesting paired with stock refills.&lt;/p&gt;

&lt;p&gt;The standard in web3 is &lt;strong&gt;two years from token creation&lt;/strong&gt;. Oh, word, and we’re planning to rebuild the internet?  Extending this vesting schedule probably won’t happen because a vesting schedule is a Mexican standoff between the investor and the founding team, and they both benefit financially by bringing their exit to USD closer to the present. The eventual “community” has nothing to do with it. For this to end up otherwise, both parties would have to make an altruistic and self-sacrificing agreement for the health of the networks they build.&lt;/p&gt;

&lt;p&gt;The problem is complicated by the fact when the network is live, the token is usually liquid (if it’s even pretending to have a purpose). Suddenly, an organization that probably has the maturity of a seed-stage startup is beholden to the public market. At this point, the product is usually too immature to be doing anything that anyone wants (other than attempting to hit it like a piñata so it drops some tokens to market-sell). The founding team finds itself answering to angry speculators who want the price to go up, but not to users. Becoming deeply useful is years of hard work away.&lt;/p&gt;

&lt;p&gt;The optimal and obvious strategy becomes yelling about techno-optimism while pretending to ship for two years until they can sell their tokens to the remaining rubes and abscond. It’s extra easy to pull off when you’re marketing to naive people who don’t understand your industry, are easily swayed by fake or misleading statistics, and are intoxicated with collective effervescence in a bull run. The lack of securities enforcement on these tokens means that people get away with saying anything they want to manipulate the token price upwards.&lt;/p&gt;

&lt;p&gt;Even for projects that haven’t rationally decided to rug, if they misalign the ponzi-versus-vesting-versus-building schedules, they can end up in situations where the team is rich and unwilling to work but the product isn’t working. Another fun one is where the system not collapsing depends on maintaining the token price and tokenholder interest, which requires a massive amount of energy from the team, and prevents them from ever focusing on building anything useful, which dooms them to an excruciatingly slow death of perpetual useless PR announcements and no users.&lt;/p&gt;

&lt;p&gt;The right way to shape these incentives is to make it so that it’s approximately the same expected value to participate early (with a small chance of hitting a jackpot on your earned token value and little useful product) as it is to participate late (with a useful product and no rewards), unless the early participant is bringing rare and useful information to the market by participating. This means that the team and investors need to be locked in for the appropriate amount of time to iterate, get the thing built, and grow it to where the incentives can take care of themselves.&lt;/p&gt;

&lt;p&gt;Secondly, users’ needs ought to be mostly figured out before non-user token-holders come into market play. You need that as baseline because that’s where you’ll get your sustained steady-state revenue after the ponzi scaling phase. In standard startup parlance, you need to achieve PMF before you dump resources into scaling. However, in crypto, the stakes are significantly higher because you can only launch the token into orbit once. You have one toss at achieving network effects through a good pump, so don’t jump until you have a plan for how you’ll stick the landing.&lt;/p&gt;
&lt;h2 id=&quot;lack-of-securities-regulation-much-time-wasting-trying-to-define-tokens-as-a-not-a-security&quot;&gt;Lack of securities regulation, much time-wasting trying to define tokens as a not-a-security&lt;/h2&gt;
&lt;p&gt;In the last section, I alluded to the lack of securities law allowing teams to exploit information asymmetries freely. I’ll discuss that further here.&lt;/p&gt;

&lt;p&gt;Much of the innovation in incentive schemes that I talked about in the first section is possible because of the lack of regulation. Realistically, the closest cousin to what we’ve built is usually some kind of security, whether it’s as simple as a growth or dividend stock, an option, or some exotic financial derivative we’ve historically banned from traditional markets.&lt;/p&gt;

&lt;p&gt;Sometimes, protocols attempt to force users to pay for services in their token, and they make the legal claim that it isn’t a security but a “utility token” more akin to a coupon or airline point, even though all their users treat it like a growth equity share. Sometimes this works out for them (Ethereum, thanks to immense network effects), sometimes it doesn’t, and they fail to force users to pay for their goods in their token (Sia, most alt-L1s).&lt;/p&gt;

&lt;p&gt;Regardless, nitpicking definitions to figure out whether a token is or is not a security is stupid. Securities regulation is meant to prevent people from scamming and defrauding each other when they trade financial instruments. Rigidly clinging to the Howey test is not useful in terms of determining which financial transactions ought to be regulated for the good of society, where the goal is to prevent people from harming each other with the practices that securities law is built to prevent.&lt;/p&gt;

&lt;p&gt;Right now, the SEC seems to be fighting very slowly through the massive fog of misinformation, and our industry is spending half its time and attention attempting to prevent ourselves from being defined as a security so that we don’t all get hit with charges for issuing and selling unlicensed securities. For me, the right answer to clean the industry up is probably amnesty for that charge in particular, retroactively defining tokens as securities, retroactive enforcement for bad-faith securities violations, and hard work writing a lot of policies to start enforcement going forward.&lt;/p&gt;

&lt;h2 id=&quot;things-are-not-well-here&quot;&gt;Things are not well here&lt;/h2&gt;
&lt;p&gt;Under all these perverse incentives and a total lack of healthy regulation to prevent crime, all sorts of ill effects have taken over the industry. To me, it has felt diseased for years now. It’s hard to take hopeful people seriously.&lt;/p&gt;

&lt;p&gt;Vampire attacks have been in vogue for a while, where a company barely innovates in anything useful except attracting more liquidity for no good reason, but they succeed in stealing liquidity from the other project that might have been more technically innovative. Zero-sum liquidity and order flow battles feel like the main frontier of innovation in the industry, with a small minority of projects trying to solve real problems instead of building a financial ouroboros. Innovation has moved from the technology and game theory to the social and memetic layers, which is not where it ought to be when our tech is still unusable and not solving problems.&lt;/p&gt;

&lt;p&gt;People have moved from launching protocols that use a token, to launching protocols with a useless token hastily glued onto the side, to launching a token with a fake protocol attached to lend the techno-optimistic bullshitting an air of legitimacy, to launching naked memecoins with absolutely nothing but the meme attached. Flagrant bullshitting has become completely acceptable, and the speculation doesn’t even pretend to be based on techno-optimism: nobody in the industry believed these goofy AI narratives, but everyone believed that the cavemen Coinbase drags in will buy.&lt;/p&gt;

&lt;p&gt;The people who are left in the industry are (with a few small pockets of exception) trapped by contract or income, too clueless to understand what’s happening, do understand but are completely past caring, or are sociopaths actively exploiting anyone they can drag into their net. This is not a recipe for bringing together smart-kind-passionate people who accomplish world-historical things with technology. This is how you attract apathetics, losers, mercenaries, and villains. What you accomplish is crime and failure.&lt;/p&gt;

&lt;p&gt;The people who are allocating capital aren’t entirely to blame, although there are a lot of them who are colluding heavily with the worst offenders, because their LPs pressure them to return the fund, and there’s not much honest money left to be made in this industry (or competent founders). Founders can’t always be blamed either because they’re making rational decisions in a social environment that finds these sorts of schemes allowable. The pressure for all parties to predatorily extract capital now at the expense of long-term value is coming from every possible direction at this point. The incentives have decayed into a nasty situation for everyone involved.&lt;/p&gt;

&lt;p&gt;As a founder, I’ve felt trapped and sick for a long time. Few in web3 want to pay for useful things because they’re all attempting to juice money &lt;strong&gt;&lt;em&gt;out&lt;/em&gt;&lt;/strong&gt; of the industry as fast as they can. If you’re trying to sell to people who aren’t in the cult, you have to make up new jargon to avoid the distasteful (well-earned) associations. In the past year, talent from within the industry is nearly always worse than talent sourced from outside, which I’ve verified across so many interviews. Teams trying to achieve product-market fit by solving real problems in people’s lives instead of playing various predatory zero-sum games are &lt;em&gt;very difficult to find funding for&lt;/em&gt; (we’re a rare exception), although every VC and ecosystem lead is constantly bemoaning the lack of founders building consumer apps to self-immolate on the pyre of a post-TGE ecosystem’s corpse.&lt;/p&gt;
&lt;h3 id=&quot;can-we-clean-it-up&quot;&gt;Can we clean it up?&lt;/h3&gt;

&lt;p&gt;I mean, maybe. We need some regulation and better norms. As I said earlier, there’s a good reason that we have the SEC, restrictions on how you can buy and sell securities, and restrictions on speech related to securities where you inherently have asymmetric information.&lt;/p&gt;

&lt;p&gt;It’s to prevent what we’ve been watching happen, to prevent all of society from exploding out of control with speculation and then rotting in its wake. Thank god this was contained to a tiny corner of the market. It’s been entertaining (albeit bloody) to watch history repeat itself and justify securities law before my once-libertarian eyes.&lt;/p&gt;

&lt;p&gt;As I said earlier, a sketch of the right approach is probably to start enforcing retroactive securities law on tokens, with an exception for offenses related to selling unregistered securities as long as everything else was done mostly in good faith. Work needs to be prioritized immediately to allow useful game-theoretic innovations without legalizing scams. There’s a fine line between “cool useful protocol” and “derivatives so complex that they’re inherently predatory”, and our regulators need to buckle down and do their homework to figure out the difference. I’m not naive, I know it won’t be easy, bureaucrats will have to analyze incomprehensible ponzi programs with millions in circular transaction volume and names reminiscent of arcade games.&lt;/p&gt;

&lt;p&gt;We already have some groundwork to start from: we know what the common scams look like and what financial crimes like manipulating markets look like. We can green-light situations and provide guidance for places where things are fine and investment is derisked- fair valuations for growth and cash-flowing tokens are something that we’ve known how to calculate for ages. It’s a difficult problem because a lot of regulation is protection from exotic derivatives that only your MIT PhD quant can understand (and not your cousin who loves /r/wallstreetbets), but exotic derivative structures are basically our whole thing. Nevertheless, we must start figuring this out if we hope to rescue anything.&lt;/p&gt;

&lt;p&gt;Secondly, we need longer vesting, long enough to build and stabilize the product. It should attempt to be scheduled to last until the end of the ponzi phase (e.g. get to where system inflows match outflows and inflation is aligned with growth, risk, and work done), with a stabilization lockup overhang to let the steady-state sit. This would be similar to waiting for the startup to have mostly saturated its target markets and be executing a robust financial model before an IPO.&lt;/p&gt;

&lt;p&gt;We also need better standards about when projects should take on the responsibility of answering to a population of tokenholders at TGE, which should be after sufficient attention has been given to serving the needs of the people who will be paying to obtain value from the protocol.&lt;/p&gt;

&lt;p&gt;The other question is, once we’ve cleaned up the piranhas, what remains to be salvaged? Very little technology is ready to solve problems for users. Much of our innovation has been into scams, infrastructure that enables scams, and infrastructure that helps people win zero-sum games. Some areas that I think have immediate hope include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;CBDCs and distributed enterprise ledgers,&lt;/li&gt;
  &lt;li&gt;stablecoins,&lt;/li&gt;
  &lt;li&gt;socialFi and regulated gambling,&lt;/li&gt;
  &lt;li&gt;privacy tech/fundamental cryptography like ZK,&lt;/li&gt;
  &lt;li&gt;and fundamental p2p/local-first/distributed systems research.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, we’re used to massively inflated valuations, because both founders and VCs are accustomed to exiting their investments in a flaming pump-and-dump. There will be carnage for venture funds if these practices end; they’ll have to significantly mark down almost all their investments. There may not be a lot of liquidity to deploy into whatever’s left, which is a problem, because there’s still a significant amount of work left before any of these products could make money.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;conclusion&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Novel incentives in code (as smart contract or distributed system) are extremely cool, and you can do really cool things with them.&lt;/li&gt;
  &lt;li&gt;People aren’t always very skilled at designing these, and when they mess up, it can go catastrophically wrong for all sorts of sad and unavoidable reasons.&lt;/li&gt;
  &lt;li&gt;There are major unsolved incentive alignment problems between the teams building the protocols, the tokenholders, and the health of the useful protocol itself. These are probably surmountable, but there are perverse incentives against fixing them.&lt;/li&gt;
  &lt;li&gt;Lack of securities regulation, and the entire industry fighting getting regulated, has led to this technology developing into a hotbed of crime and scams. We have built financial products that nearly always ought to be regulated as a security for the good of society, but instead of attempting to work with regulators, we’ve mostly acted like children (and are now receiving our just Wells notices).&lt;/li&gt;
  &lt;li&gt;We are seeing increasingly short-sighted, extractive, and wasteful behavior across the industry. Meanwhile, the industry rots from the inside out as everyone except the bottom of the barrel flees. However, individuals aren’t entirely to blame for this sad situation, because perverse and powerful incentives are coming from all sides at this point.&lt;/li&gt;
  &lt;li&gt;I believe a quick and brutal cleanup is both possible and desirable: the SEC should retroactively consider almost all tokens securities by default, grant amnesty to projects that sold unregistered securities in the past and ongoing until better regulation has been developed, and start aggressively prosecuting the most egregious and predatory violators from the past few years (as in, &lt;em&gt;probably not&lt;/em&gt; Uniswap and Coinbase, certainly not to an existential level of judicial attack)&lt;/li&gt;
  &lt;li&gt;Longer-term (but starting immediately), the SEC ought to rapidly develop some guidelines against the worst scams (inspired by the obvious parallels in history and securities law) and start a good-faith collaboration on figuring out how to constructively regulate complex financial incentive schemes over distributed systems that are marketed to non-accredited investors.&lt;/li&gt;
  &lt;li&gt;This will be a bloodbath for crypto VC funds and many founders. What’s left may feel small and sad, and venture interest may dry up for a while. That’s okay because we’ll be left with the core of what’s true and valuable. If the technology is truly useful, we’ll eventually get back on our feet, this time stronger without parasites.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Will we ever get PMF as a better money?</title>
   <link href="https://w.laudiacay.cool/2024/05/22/are-we-building-money.html"/>
   <updated>2024-05-22T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/05/22/are-we-building-money</id>
   <content type="html">&lt;p&gt;This post will discuss the possibilities in the market for blockchain-based money and financial products outside of speculation. I will argue that the situation isn’t great.&lt;/p&gt;
&lt;h3 id=&quot;the-product-market-fit-of-money-is-the-stability-and-ease-of-transacting&quot;&gt;The product-market-fit of money is the stability and ease of transacting&lt;/h3&gt;

&lt;p&gt;The thing about money itself is that you don’t want it in itself, you want it because you think someone else will accept it in the future, in exchange for something that you do want. Good money is a bubble that doesn’t pop, because the forces buoying its value upwards (e.g., collective dreams like trust in its future value and exchangeability) are stronger than the forces dragging it back to its wretched little reality as a slip of paper, a lump of shiny metal, an entry in a database, or a u256 in the Ethereum state.&lt;/p&gt;

&lt;p&gt;The US dollar is historically a somewhat stable money. The powerful US government backs it, and although their level of fiduciary responsibility to minority dollar holders has been under question lately as they massively dilute the share pool, we have spent the past 10 years feeling largely comfortable that we’ll be able to buy yogurt for a price within an order of magnitude of where it sells today.&lt;/p&gt;
&lt;h3 id=&quot;dissecting-the-fiat-moat&quot;&gt;Dissecting the Fiat Moat&lt;/h3&gt;

&lt;p&gt;A huge number of “micro-forces” are constantly re-centering the dollar’s value. Every time an exchange takes place, both parties nod at the value of the dollar in terms of its purchasing power for concrete goods with use-value. Every second, the dollar is hammered into human minds as having the possibility to rapidly turn into a concrete parcel of yogurt, gas, financial risk, stock, weapons, drugs, animals, land, sex, medicine, or movie tickets.&lt;/p&gt;

&lt;p&gt;Uncertainty about the value of the dollar is (most of the time) squishy and theoretical for the average person, measured in “9% inflation over a year”- a tenth of a dollar over a full year of paychecks. You can make arguments about the dollar (and &lt;a href=&quot;https://twitter.com/mikojava&quot;&gt;Miko&lt;/a&gt; did) having devalued 93% in a century, but the frog seems pretty happy in its rapidly warming pot, for all Coinbase’s beautifully constructed propaganda. Read “When Money Dies” for a beautifully documented historical example of what goes down during hyperinflation in a developed society very similar to our own- the details shed a lot of light on how you can expect humans to behave.&lt;/p&gt;

&lt;p&gt;People express feeling short USD annually in elections, complaining online about the government, or (for hedge funds and doomsday preppers) hedging. Almost nobody shorts USD by churning away from using USD. The threat of catastrophic hyperinflation is a distant black swan that we all mostly ignore, which is necessary for society to continue functioning.&lt;/p&gt;

&lt;p&gt;Certainty about the dollar is thrown in our faces daily, and is measured in being able to obtain Chipotle with (lately a somewhat larger amount of) Apple Pay US Dollars. People express their certainty about USD daily by continuing to participate in the dollar economy instead of defecting to euros, yuan, gold, or canned goods, and they constantly witness others expressing these signs of certainty and stability as they participate in the market.&lt;/p&gt;

&lt;p&gt;This leads into the other side of fiat’s moat: Your bartender and your grocer and your barber and your landlord and your tax-man all take USD. You will carry a method of giving them USD until almost all of them no longer accept USD. To start inconveniencing yourself to carry Money2, you’ll need to expect be forced to pay Money2 when you’re doing errands, which statistically means a sizable chunk of places will need to accept exclusively Money2. But &lt;em&gt;they&lt;/em&gt; won’t accept it until &lt;em&gt;everyone else does&lt;/em&gt; either.&lt;/p&gt;
&lt;h3 id=&quot;money-is-extremely-hard-to-dislodge&quot;&gt;Money is extremely hard to dislodge&lt;/h3&gt;

&lt;p&gt;Between these two factors, we see a very powerful self-reinforcing emergent phenomenon that coexists well with the human tendencies to discount theoretical future risks, prioritize immediate needs, prioritize convenience, and go along with the group opinions. Money evolved with our society, and we need it as much as it needs us, but the relationship is mostly very comfortable and stable.&lt;/p&gt;

&lt;p&gt;Some users get an extremely bad UX with the fiat money in itself, like people in countries with hyperinflation or cash shortages, but this is historically quite rare. A serious inflation event that dislodges the day-to-day trust in money, combined with good UX of stability on an alternative solution, could theoretically pull people away from fiat money. People are not likely to undertake the extremely costly move of moving money systems without a societal catastrophe, and the government is not likely to facilitate it. Additionally, they’re much more likely to move to a different fiat money system that excitedly welcomes them into a usable and well-developed infrastructure.&lt;/p&gt;
&lt;h3 id=&quot;can-crypto-expect-to-dislodge-users&quot;&gt;Can crypto expect to dislodge users?&lt;/h3&gt;
&lt;p&gt;No crypto (except pegged assets) has the requisite stability or widespread usage to tick either of these boxes. The forces weighing on the prices of Bitcoin and Ethereum (the most stably valuable non-pegged assets) are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;the price of electricity or risk-free rates (for proof of work and proof of stake) (small effect),&lt;/li&gt;
  &lt;li&gt;the day-to-day noise of retail speculation (small effect),&lt;/li&gt;
  &lt;li&gt;the demand for blockspace based on user volume in various apps (none with a durable user base) (small effect),&lt;/li&gt;
  &lt;li&gt;and the macro trends of ETFs and other institutional capital inflows, government regulation, risk-off behavior during low interest rates, which drive large momentum from follow-on retail and institutional speculation. (in combination, an extremely large effect)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes Bitcoin and Ethereum unsuitable candidates for being money in themselves. There isn’t any quick go-to-market that I see to get them to that point- even if crypto gets traction, people will defect to using stable pegged assets atop them, because of the volatile forces above. The stability of fiat comes from the network effects, but is also a precursor to achieving product market fit and growth. Extremely problematic.&lt;/p&gt;

&lt;p&gt;An economic catastrophe like dollar hyperinflation is not bullish for crypto, except via the secondary effects of institutional buys who believe the thesis that fiat collapse means crypto success. Economic collapse is likely to push people to join a currency zone with existing stability, infrastructure, and network effects. As I alluded to earlier, the owner of the incoming currency zone will shovel resources into promoting this shift, because it cements their soft global power over the collapsing economy. We’ve seen this historically over and over again in cases of colonization, predatory “development” investing, hyperinflation, and governmental collapses.&lt;/p&gt;

&lt;p&gt;Unpegged cryptos without nation-state support lack the power, stability, and usable infrastructure to properly take advantage of these situations.&lt;/p&gt;

&lt;p&gt;As I see it, Bitcoin and Ethereum may be investable as short-term macro or regulatory bets, medium-term bets on their ecosystems’ product-market fit, or long-term (in my opinion clumsy) fiat hedges, but they won’t be finding product-market fit as money.&lt;/p&gt;
&lt;h3 id=&quot;are-gas-fees-bullish-theoretically-yes-but-practically&quot;&gt;Are gas fees bullish? Theoretically, yes, but practically…&lt;/h3&gt;
&lt;p&gt;Gas fees could stabilize the price of Ethereum or Bitcoin by having demand for network compute becoming the predominating factor in the price. However, this could only happen by getting stable, scalable product market fit for apps built atop them. The only app that really &lt;em&gt;can&lt;/em&gt; be built atop Bitcoin is Bitcoin, which creates a bit of a chicken and egg situation, because Bitcoin is not good money. The only apps atop public blockchains like Tron and Ethereum that seem to have strong and durable product-market fit are Farcaster (durable crypto social), ponzi-scheme timing games and other popular casinos (Uniswap, DeFi, pump.fun, OpenSea), and stablecoins/RWA (proxies for non-digital value, intended for avoiding transaction UX problems).&lt;/p&gt;

&lt;p&gt;I have more theoretical arguments about why other apps don’t need blockchains, but the fact that these are the only ones that have non-farming stabilized demand after fifteen years of web3 and billions of dollars of capital investment is a sufficient argument, in my opinion.&lt;/p&gt;

&lt;p&gt;The first two are easy to strike out as non-durable/scalable and unlikely to make a public blockchain’s gas token stable enough to be used as “world money”. Farcaster only has product-market fit because people believe in crypto (or, cynically, want to land on the right side of a ponzi)- another chicken-and-egg that can’t necessarily scale to become a massive emergent phenomenon like money. Our gambling is a prime target for regulation, especially because our casinos are more degenerate and predatory than any house in Vegas, and we are virtually a news factory for ugly high-profile fraud cases. Stablecoins are… a bit more promising.&lt;/p&gt;
&lt;h3 id=&quot;stablecoins-and-rwas&quot;&gt;Stablecoins and RWAs&lt;/h3&gt;
&lt;p&gt;Pegged assets’ suitability to be “proxy fiat” obviously depends on the quality of the peg, as we’ve seen throughout crypto.&lt;/p&gt;

&lt;p&gt;The highest-quality fiat pegs hold treasury bonds in a high-quality DAO or regulated and audited entity, and track balances on-chain in an ERC20. This makes them more or less a standard bank, except with their database on a blockchain. This also opens them up to regulation, because the most trustworthy design for an on-chain asset involves a centralized entity that can be laser-targeted by regulators. Obviously, this is a prime target for regulation and regulatory capture. Therefore, I am not convinced that the blue-chip stablecoins’ product-market fit atop existing public blockchains is scalable: even at our current small level of traction, Circle supports sanctions for USDC as a first-class feature. Clearly, the government could twist their arm to do much more.&lt;/p&gt;

&lt;p&gt;The highest-quality RWA pegs are in the same situation. It is very rare to have a purely digital object with real and non-speculative stable value: data brokerage is harebrained for reasons I’ll eventually write about, and decentralized cloud as a digital commodity is a shitshow for reasons I’ll also eventually write about. Most “digital” products are a title of a physical object, which is secretly just a piece of paper that lets you point the government’s monopoly on violence at whoever claims they own your thing. This means the guarantor of the title (DAO, company with a smart contract, whoever) needs to be able to back up their claims to be able to enforce the state of the database in the real world. They either need to be able to (and trusted to) protect the resources themselves, or the government needs to recognize that this company and its smart contract is reflecting real enforceable property rights. These are, once again, an obvious target for regulation and regulatory capture, and the only reason we don’t see pushier enforcement is that none of them have sizable traction.&lt;/p&gt;

&lt;p&gt;“Well, fine, the RWAs and stablecoins can just coexist with regulation and exist happily in crypto, so my Ethereum bag is fine after all!” Actually, no. The regulatory burdens will only increase with time and traction, because we are messing with the financial system, which is a cherished US government muscle for soft global power.&lt;/p&gt;

&lt;p&gt;An entity or consortium that can regulatory-capture stablecoins, RWAs, and CBDCs will have no reason to pay a gas royalty to the Ethereum network or even use a non-proof-of-authority blockchain. This entity or consortium is likely to be someone with finance, government, and NGO connections, who defects from the “web3 community” to build their own thing to the precise specification of the powers that be. In fact, this startup probably already exists, is working their network, and will bring a product to market by 2030. Meanwhile, a project that is successfully dodging regulators and executing on the anarcho-capitalist dream will never be allowed to scale beyond pockets of criminals and the dispossessed.&lt;/p&gt;
&lt;h3 id=&quot;our-win-wont-be-money-it-is-banking-for-niche-markets&quot;&gt;Our win won’t be money. It is banking for niche markets.&lt;/h3&gt;
&lt;p&gt;I won’t comment further on the competitive landscape of CBDCs and regulated RWAs because I’m not a regulatory expert, but I will say a few words about the “anarcho-capitalist dream” market.&lt;/p&gt;

&lt;p&gt;Cash and checks had a shitty UX, so we now use digital US dollars administered by tightly-regulated banks who occasionally gently fuck us with overdraft fees, hazing about attempted withdrawals and wire transfers, sanction enforcement, and account closures. These bad things aren’t bad enough for most users to churn, so we all mostly use Apple Pay and Chase. There are a few exceptions to this rule, and those are what’s capturable.&lt;/p&gt;

&lt;p&gt;Some users have an extremely bad UX with banks and money in ways that haven’t been solved yet. This includes people in industries that the banks feel are too risky to serve (drug dealers, organized crime, sex workers, crypto buyers, marijuana industry, startups, sanction evaders), people who are attempting to wire money overseas between shitty or incompatible banking systems, and people who exist in states with unstable, inflated, cash-insufficient, or otherwise degraded money systems. The overwhelming majority of transaction volume is not here, but we can serve these people.&lt;/p&gt;

&lt;p&gt;In fact, we do, and that’s probably most of the non-speculative non-farming volume across the entire industry. There is certainly more market to capture, and more little niches within these segments to find and serve. Tron and USDT, people who slip through the gaps with USDC, privacy coins and swaps, and Venmo-like transfer apps are all finding strong product-market fit when they successfully go to market with people who are underserved with the banking industry.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;All this is to say that the FDV of non-pegged public-blockchain L1 tokens should not ever be expected to grow to the market size of “money”. If you remove the enormous speculative markups, the correct valuation as a long-term asset is probably the expected distributed computation and consensus overhead costs to process the transaction volume of underserved people who churn from fiat due to UX issues with banks, regulation, or the money itself.&lt;/p&gt;

&lt;p&gt;Arguing for expanded market caps on most of these assets is nonsensical. Maybe the word for it isn’t “fraud”, but it’s in the neighborhood. I don’t think there’s a navigable path to market capture, because the lack of stability and lack of network effects present a chicken-and-egg problem without the power of a nation-state to catalyze and enforce the currency on the market.&lt;/p&gt;

&lt;p&gt;Technological issues are entirely orthogonal to the real problem.&lt;/p&gt;

&lt;p&gt;Stablecoins and RWAs could print money, but most non-speculative value lies off-chain, and only the really good pegs are trustworthy. “Really good” means holding treasury bonds and legacy signifiers of trust and compliance. The ones that can capture sizable chunks of consumer and intra-financial-institution volume will not be built on public blockchains, and will be almost completely regulatorily captured, because the powers that be are both powerful and quite defensive of their monetary power.&lt;/p&gt;

&lt;p&gt;I think we have found one durable PMF as peer-to-peer money for more organized and intelligent criminals. Tron/USDT is on a winning path to being a regulatory-loophole cross-border money for people and nations who are financially dispossessed.&lt;/p&gt;

&lt;p&gt;We also have strong PMF for getting large sums of capital out of restrictive markets (China) in a legitimate-seeming way, although that’s not happening through simple token transfers, it’s happening via venture capital deals, which is a story for another time.&lt;/p&gt;

&lt;p&gt;I find the equity of CBDC and RWA startups with extremely strong (interpersonal and professional) networks in government and finance highly investible.&lt;/p&gt;

&lt;p&gt;I also might make a bet on the tokens of projects with a plausible case for strong consumer go-to-market (do not underestimate how difficult this is…) among a financially dispossessed niche, with a team that’s properly offshored and trained for jiu-jitsu with both nation-states and organized crime.&lt;/p&gt;

&lt;p&gt;If I could bet on the market cap of USDT, I would. I am not comfortable with buying TRON token as a bet on their network size, for obvious Justin Sun reasons.&lt;/p&gt;

&lt;p&gt;I am not bullish about much else around here “becoming money” or “eating all land deeds”.&lt;/p&gt;

&lt;p&gt;Not financial advice. Ever. Why would you take financial advice from me. Please refrain.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tutorial Introduction to MDL</title>
   <link href="https://w.laudiacay.cool/2024/05/11/Tutorial-Introduction-to-MDL.html"/>
   <updated>2024-05-11T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/05/11/Tutorial-Introduction-to-MDL</id>
   <content type="html">&lt;h3 id=&quot;source-post-here&quot;&gt;&lt;a href=&quot;https://arxiv.org/pdf/math/0406077&quot;&gt;Source post here.&lt;/a&gt;&lt;/h3&gt;

&lt;h2 id=&quot;under-construction-as-of-may-13-2024-please-excuse-the-awful-formatting-im-working-in-markdown-and-not-compiling-to-html&quot;&gt;UNDER CONSTRUCTION! as of may 13 2024. please excuse the awful formatting, I’m working in markdown and not compiling to HTML&lt;/h2&gt;

&lt;p&gt;What a great start, this is eighty pages long. It’s remarkably friendly- if you’re using my notes to skip the papers, maybe just go read this one and refer back to my notes when you’re having trouble parsing something. (or want some fun Claudia insights about applications to broader ML/my one true love cryptography)&lt;/p&gt;
&lt;h4 id=&quot;background&quot;&gt;Background&lt;/h4&gt;
&lt;p&gt;The start of the paper: the MDL (Minimum Description Length) is a method for inductive inference. What’s inductive inference, you ask? It’s the task of finding a general model from a finite set of training data. You want to fit the observed data well, but also generalize to data from the same distribution that you haven’t seen before.&lt;/p&gt;

&lt;p&gt;If you’ve heard the terms “underfitting” and “overfitting”, those are describing not fitting the observed data well enough (e.g. not learning enough about it to predict future observations well), and fitting the observed data too well (e.g. seeing patterns that aren’t there and messing up accordingly on future observations).&lt;/p&gt;

&lt;p&gt;MDL more or less says that any pattern you find in the data can be used to compress the data. The more you’ve learned about the data, the more you’re able to compress it, and vice versa. You want to minimize both the length of the description of your model, and the length of the observations given the description of the model, and then you’ll be able to predict the future (sort of).&lt;/p&gt;

&lt;p&gt;MDL has some extremely nice properties:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;it looks like Occam’s razor,&lt;/li&gt;
  &lt;li&gt;it naturally protects against overfitting, unlike maximum likelihood estimators&lt;/li&gt;
  &lt;li&gt;It has a Bayesian-ish vibe, but avoids the weird interpretation issues when we know there’s not REALLY a ground-truth distribution to learn&lt;/li&gt;
  &lt;li&gt;it doesn’t make any assumptions about whether there is some “underlying truth” (great, nobody who studies language today is a hardcore Platonist)&lt;/li&gt;
  &lt;li&gt;data compression and prediction are formally equivalent for a certain definition of prediction, MDL is leveraging this in order to predict
    &lt;h3 id=&quot;kolmogorov-complexity-for-compression&quot;&gt;Kolmogorov Complexity for Compression&lt;/h3&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start: imagine some sequences of bits, like “101010” (a pattern) and “111011111011110101” (far more ones than zeros but otherwise random) and a completely random string. The ones with regularities you can spot are compressible with some O-notation bound on how compressible it is.&lt;/p&gt;

&lt;p&gt;The next step is how we should go about compressing these strings, and we go with Kolmogorov Complexity. If you can write a computer program that is able to write the sequence out, and the computer program is shorter than the length of the sequence, you have successfully compressed it. Kolmogorov Complexity is defined as the length of the shortest computer program that prints out the sequence in question. This sounds really arbitrary and up to choice of programming language, but it turns out &lt;a href=&quot;https://dl.acm.org/doi/pdf/10.1145/321495.321506&quot;&gt;there’s a proof&lt;/a&gt; that asymptotically all programming languages are only a constant factor apart.&lt;/p&gt;

&lt;p&gt;Backing up from this definition of Kolmogorov Complexity, you can get an “idealized MDL” for an “ultimate model of the data”, which is exactly just this shortest computer program… Unfortunately, this is both practically uncomputable (there’s a proof saying as much), and is dependent on the syntax of the programming language you choose. So, in reality, you take “practical” approaches to finding an MDL predictor, by using description methods that know things about the specific problem domain, generally doing the best you can in the situation.&lt;/p&gt;
&lt;h3 id=&quot;practical-mdl-starting-with-crude-mdl&quot;&gt;Practical MDL, starting with “Crude MDL”&lt;/h3&gt;

&lt;p&gt;Grounding: We start with the simple example of picking a good polynomial estimation from a set of points without over or under fitting. Then we define some terms: “hypothesis” as a single probability distribution (in this case, a single polynomial), and “model” is a family of probability distributions with the same form (second-degree polynomials). Note how this maps onto our intuition from machine learning: a model is how you wire up the layers in Tensorflow and set up training, a hypothesis is a frozen-in-time partly-or-completely-trained model that you might test on a holdout set.&lt;/p&gt;

&lt;p&gt;Next- we’ve finally arrived at some math! A crude definition of MDL. We define the “best model” in a simplified setting where we have a list of candidate models ($H_1$, $H_2$, $H_3$) containing hypotheses… imagine each one is “the set of all polynomials of degree N”. And we have a bunch of data we’re trying to explain, $D$.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;$L(H)$ is the length in bits of the description of the hypothesis&lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;$L(D&lt;/td&gt;
          &lt;td&gt;H)$, length of data given $H$, is the length in bits of the description of the data when you use the hypothesis to explain the data. This will be minimized with a well-chosen $H$, so you only have to encode discrepancies between $D$ and $H$ as an error term. More about this in a second&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;table&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;The best model is the one that minimizes $L(H) + L(D&lt;/td&gt;
          &lt;td&gt;H)$- fitting $D$ well without packing so much information into $H$ that it explodes in size&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Now let’s make things more concrete. We’ll start with $L(D&lt;/td&gt;
      &lt;td&gt;H)$: Assume $Y=H(X) + Z$, where $Z$ is a noise term. To encode these errors, they’re using something called the Shannon-Fano code, which is not defined concretely but is proven to exist for all data sequences, and has length $L(D&lt;/td&gt;
      &lt;td&gt;H) = -\log P(D&lt;/td&gt;
      &lt;td&gt;H)$. This looks sort of like Huffman coding to me, but I think it’s maybe not actually defined over all probability distributions over the rational polynomials. But claim there’s a proof of existence in section 2.2, so I can’t wait to check it out.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Defining $L(H)$ gets a bit harder: How do you code hypotheses? Your choice of code affects the outcome of the procedure, because the same hypothesis can vary wildly in length based on code choice. We need to refine MDL a bit to make this make sense…&lt;/p&gt;

&lt;h3 id=&quot;refined-mdl&quot;&gt;Refined MDL&lt;/h3&gt;
&lt;p&gt;The first thing is to smush the encoding into one part: you encode $D$ with respect to the entire model, instead of given one hypothesis. You design the code so that when there’s a member of the model class that fits the data well ($L(D|H)$ small), you get that $\bar{L}(D|\text{model})$ is also small. This $\bar{L}(D|\text{model})$ is called the “stochastic complexity” of the data, given the model.&lt;/p&gt;

&lt;p&gt;Next, we add something called the “parametric complexity” of the model, denoted $\textbf{COMP}(\text{model})$, which is a measure of how rich the model is, e.g. the “geometrical structure and degrees of freedom”, which also indicates how well it fits random data.&lt;/p&gt;

&lt;p&gt;There’s a relation between parametric complexity and stochastic complexity- let $\hat{H}$ be the distribution in the model that maximizes the probability of $D$ and therefore minimizes the complexity of the hypothesis.
\(\bar{L}(D|\text{model})= L(D|\hat{H}) + \textbf{COMP}(\text{model})\)
Note that this is the same as one of the early attempts at calculating “crude MDL” mentioned in the paper, where the researchers were choosing hypothesis codings that would minimize this term… Except this one cleverly elides the hypothesis coding problem entirely, so there’s no arbitrariness, and you get something concrete that you can compute.&lt;/p&gt;

&lt;p&gt;The paper goes on to list four interpretations of this definition:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Counting states: parametric complexity of a model is the logarithm of distinguishable hypotheses within it&lt;/li&gt;
  &lt;li&gt;Two part coding: we’re reducing back to the crude MDL definition, e.g., stochastic complexity is a two part code’s length, where you break the model into “maximally distinguishable hypotheses” and then just assign them all the same codelength ($\textbf{COMP}(\text{model})$)&lt;/li&gt;
  &lt;li&gt;Bayesian: a non-informative prior aims to minimize the bias introduced by prior assumptions onto the bayesian inference procedure as you learn over data. This procedure is more or less doing the same thing- it’s picking the model based on minimizing the code length of a best-fit hypothesis for random data.&lt;/li&gt;
  &lt;li&gt;“prequential interpretation”: you’re selecting the model with the best performance on unseen test data. This means that you’re encoding everything you know about the problem and nothing else, and leaving the model training to handle your hypothesis test: e.g., optimal breakdown of the problem!
    &lt;h3 id=&quot;rissanens-philosophy-about-mdl&quot;&gt;Rissanen’s philosophy about MDL&lt;/h3&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rissanen invented MDL.&lt;/p&gt;

&lt;p&gt;His thoughts about it: you don’t want to assume the observed data was generated by a distribution and try to fit. Instead, you want to start with almost nothing assumed about the structure of the data, and you just want to wring as much “regularity” out of the data as possible in order to learn about it (and therefore compress it).&lt;/p&gt;

&lt;p&gt;Second, he interprets models as languages for describing the useful properties of data, and hypotheses are to be interpreted as metrics and statistics about the data seen, that summarize certain regularities. They’re meaningful regardless of whether the hypothesis is the “state of nature”, which honestly… if you look at human language… would be a pretty silly thing to talk about. Additionally, noise is not defined relative to some theoretical probability distribution, but as relative to the model once you’ve found the hypothesis and observed the data- e.g., it’s the remainder after you’ve pulled out as much regularity as you can using the current model! It’s just a measure of how good the model can suit the data in question.&lt;/p&gt;

&lt;p&gt;Third: do not use methods of inductive inference that assume there’s a “true state of nature” you’re attempting to approximate. These methods (Markov models for language generation, anyone?) have incorrect assumptions that will bound their “fit” to reality. They can still be useful, but they’re not learning from the data alone, they’re learning from the data while hobbled by incorrect assumptions.&lt;/p&gt;

&lt;p&gt;Fourth:&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Understanding LSTM Networks</title>
   <link href="https://w.laudiacay.cool/2024/05/09/Understanding-LSTM-Networks.html"/>
   <updated>2024-05-09T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/05/09/Understanding-LSTM-Networks</id>
   <content type="html">&lt;h3 id=&quot;source-post-here&quot;&gt;&lt;a href=&quot;https://colah.github.io/posts/2015-08-Understanding-LSTMs/&quot;&gt;Source post here.&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This post is a kind and simple introduction to RNNs (Recursive Neural Nets) and the magical LSTM (a special kind of RNN, a Long Short Term Memory network). RNNs allow the neural net to have continuity of thought- they build up a context from intermediate states as they observe them in order, outputting information and editing the internal context based on each state they see, to allow contextual processing that streams forward in time. RNNs work by forwarding context from one iteration to the next as it steps through inputs, adds them into the context, and outputs outputs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rnn.png&quot; alt=&quot;rnn&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;rnns-have-to-do-a-hard-task&quot;&gt;RNNs have to do a hard task.&lt;/h3&gt;

&lt;p&gt;Hopefully, this allows the net to do things like answer the query: “The dog ate my spaghetti. Who ate my spaghetti?”. By the time the RNN has finished parsing the entire query, it needs to have encoded into its context both that we’re looking for the naughty spaghetti eater, and that that was an (adorable) dog. The dog was seven whole tokens, seven whole iterations of net, before we get to the end. So obviously, this needs to be safely stored somewhere until it’s question-answering time.&lt;/p&gt;

&lt;p&gt;In a traditional RNN, that was usually just one tanh layer. And did that tanh layer ever have a ton of jobs to do! To simplify, let’s assume that it’s just trained on a lot of English prompts where there are one or two simple statements and then a simple question with the answer in the first two statements.&lt;/p&gt;

&lt;p&gt;To perform on this task, it has to encode English grammar and parts of speech, from token embeddings. It has to learn that the answers to questions are likely to be “interesting”, so it chooses well what to remember, because it is compressing and combining its inputs into its internal state as it runs. It has to learn a simple model of relationships between objects in the world so that it doesn’t think that the spaghetti ate itself! And it has to remember both dog and spaghetti and their relationship until output time, correctly disambiguate between them once it gets to the end of the question, and know when to forget irrelevant information.&lt;/p&gt;

&lt;p&gt;None of these are easy tasks, and it’s probably quite a bit to train into a single tanh layer to both learn about all these relationships and all of this choosing where to focus its attention and how to load its small memory choosily, because it can’t go back to re-scan the start of the sentence.
&lt;img src=&quot;/assets/images/rnn-tanh.png&quot; alt=&quot;rnn-tanh&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;they-fail-at-this-hard-task-lstms-succeed&quot;&gt;They fail at this hard task. LSTMs succeed.&lt;/h3&gt;

&lt;p&gt;This intuition turns out to be correct. RNNs with this architecture are not good at learning long term dependencies. They forget things. The solution that the LSTM presents is basically giving them a better way to store and organize information rules as they train. You’re hard-coding that the internal layers of the RNN need to do the following when they see each input token and recall the most recent output token: forget some information from the old state, add some other information to the old state, and output a token.&lt;/p&gt;

&lt;p&gt;The relationships between these are below. The first sigmoid layer picks things to ablate from the memory based on x_t (new input token) and h_{t-1} (last output token). The next sigmoid layer distorts the things we’re going to add to the context, by creating weights with which to scale what we’re adding to the new context, based on the same input. The tanh layer encodes &lt;em&gt;what&lt;/em&gt; we’re adding into the context, again based on the same input. Then we multiply them and add that to the context. Finally, we tanh the context, take a sigmoid layer on the most recent updates (to decide how they impact the output), multiply them, and out comes our next output token. Then this output token and our context go back into the next iteration of the neural net.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/lstm.png&quot; alt=&quot;lstm&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note that all of these functions are smoothly differentiable, which makes for nice backpropagation during training, and each little net inside the RNN now has a defined question to answer, so the original RNN monolayer doesn’t have to learn how to learn anymore.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;What new information does this new input token, and the presence of the last output token, bring me about the things I can forget about from the context if I want to perform well on my task? (sigmoid 1)&lt;/li&gt;
  &lt;li&gt;What does the last output and the new input tell me about what I need to add to the context to perform well? (tanh)&lt;/li&gt;
  &lt;li&gt;What does the last output and new input tell me about the changes from the old context to the new context? (sigmoid 2)&lt;/li&gt;
  &lt;li&gt;Finally, what do I output, based on the updated context, last output, and new input? (sigmoid 3)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now it just has to learn to do these four tasks, which still includes all the english structure, but omits all the learning about learning and how information relates through time and sentence structure. And, unsurprisingly, with this issue fixed, LSTMs learn long-term dependencies much better than the Vanilla RNNs we started with.&lt;/p&gt;

&lt;h3 id=&quot;insights-for-future-developments-spoiler-alert&quot;&gt;Insights for future developments (spoiler alert!)&lt;/h3&gt;

&lt;p&gt;There are a few interesting things I notice about these four questions.&lt;/p&gt;

&lt;p&gt;First: 1, 2, and 3 are not clearly defined as separate. If these three were roles in a startup, I’d expect them to fight a lot about boundaries of responsibility! The &lt;a href=&quot;https://arxiv.org/pdf/1406.1078v3&quot;&gt;GRU&lt;/a&gt;, Gated Recurrent Unit, is a paper that also notices this, and combines these three layers into one “update” layer. This shrinks the number of connections, probably, so they’re probably more efficient to train? I remember my professors saying that these had similar performance to LSTMs, and we used them in class for projects.&lt;/p&gt;

&lt;p&gt;Second: this architecture is really making some hardline decisions about chopping up the information that layers have access to! And not everything has access to the cell state, which I think would be important for deciding what to forget- as a (wildly unsuited to this architecture) example, an AP History AI that’s “studying” a textbook would be able to heavily discount any information that it detects as being inside a footnote, because that’s unlikely to be on the test. &lt;a href=&quot;https://ieeexplore.ieee.org/document/861302&quot;&gt;Peephole connections&lt;/a&gt; are the solution to this- they patch the cell state back in as an input to the gate. Greatly increased number of weights here, but it’s able to learn to count (and probably improve on some other tasks, as well).&lt;/p&gt;

&lt;p&gt;Finally: I don’t feel like I read straight through anything. I jump around until I feel that I have context, filling gaps and reinforcing concepts until I walk away with the answer to my question. One solution to this, unmentioned in this post, is a bidirectional LSTM (which I wrote in grad school). It parses backwards as well as forwards- building up state in both directions, and then putting the context from both directions into the final output tokens. From the image below, you can probably work out where the wires end up going. This helps somewhat with broadening context and allowing more flexibility in where the “blinders” are allowed to go when the LSTM is looking at inputs. Even more complex is the multi-layered LSTM, where you have multiple layers that take prior states as inputs, washing back and forth through inputs and outputs. These architectures are sort of ungodly, I had to implement this in grad school as well. They do work though.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/bidirectional-lstm.png&quot; alt=&quot;bidirectional lstm&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But- (Billy Mays voice)- there has to be a better way than “you can go forward, or you can go backward, and sometimes you can do both, but jumping around like a human does is out of the question”, right? and it can’t be mapping onto the human analogue of zipping your eyes around a 2D page, or zipping your brain around a knowledge graph of squishy mental associations, because that’s a not only a bunch of unnecessary information for most LLM tasks, but also immensely computationally intractable.&lt;/p&gt;

&lt;p&gt;The answer turns out to be something called attention, which lets the LLM take a holistic view of the entire sequence at each output, train on spotting important things from it, and think from there. This is something that we started by layering onto the LSTMs and RNNs, and then we let this tech drive on its own with no RNN in 2017 when we invented the transformer. Transformers are the architecture that brought you chatGPT and working machine learning. As it turns out, teaching the nets how to learn with LSTMs was pretty good, but letting them learn how to learn with attention layers was what brought them near human-level cognition. Read about that in another post from this series later on :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>C2PA Bear Thoughts</title>
   <link href="https://w.laudiacay.cool/2024/05/09/C2PA-Bear-Thoughts.html"/>
   <updated>2024-05-09T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/05/09/C2PA-Bear-Thoughts</id>
   <content type="html">&lt;p&gt;This is a &lt;a href=&quot;https://twitter.com/_laudiacay/status/1788594843360416242&quot;&gt;Twitter thread&lt;/a&gt; I posted about C2PA, reproduced and edited here for posterity because my Twitter auto-deletes.&lt;/p&gt;

&lt;p&gt;Today, TikTok joined the CAI (content authenticity alliance). What does this mean for blockchain people trying to make money from AI safety/data/provenance? Tl;dr, it’s not a great situation, but we already sort of knew that.&lt;/p&gt;
&lt;h3 id=&quot;who-is-the-cai&quot;&gt;Who is the CAI?&lt;/h3&gt;
&lt;p&gt;For some background: what do you need to know about the CAI? Really, the below screenshot says plenty. It’s Adobe-led (which means most creative production), using specifications whose development was incubated by the Linux Foundation (C2PA).&lt;img src=&quot;/assets/images/C2PA.png&quot; alt=&quot;Image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note the market share of social media / content delivery platforms, camera brands (Sony/Canon/Nikon), media and PR institutions (NHK/BBC/Publicis Groupe), large market share of devices and software (Intel/ARM/Google/Microsoft), and more. They’re all in the C2PA. Check the &lt;a href=&quot;https://c2pa.org/membership/&quot;&gt;members list&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;what-are-they-selling&quot;&gt;What are they selling?&lt;/h3&gt;
&lt;p&gt;They’re not selling anything, they’re just promoting open-source technology. Now let’s look at the technology involved here: w3c verified credentials, and chains thereof. C2PA is more or less a format for passing around, creating, and consuming stacks of attestations about content.&lt;/p&gt;

&lt;p&gt;If you want to deep-dive, this document is very helpful because it shows “C2PA in context” instead of making you comb through piles of “the first three bytes MAY BE reserved” RFC bullshit: &lt;a href=&quot;https://t.co/fIam3rlNkw&quot;&gt;https://c2pa.org/specifications/specifications/1.2/guidance/Guidance.html…&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;worked-c2pa-example&quot;&gt;Worked C2PA Example&lt;/h3&gt;
&lt;p&gt;For your ease of mindless scrolling, I’ve written a worked example through the entire data supply chain, with UX consideration at every step.&lt;/p&gt;

&lt;p&gt;You snap a photo. Your Canon generates a hardware signature using an onboard PUF (physically unforgeable function) or an SGX/TEE with a certificate chain back to the manufacturer. This is encoded into a verifiable credential and added to the attestations.&lt;/p&gt;

&lt;p&gt;You transform the photo into a PNG. The app (let’s say it’s Imagemagick?) either signs some attestation that it performed the transformation in SGX, or generates a ZK proof of the transformation (see this blog post by Dan Boneh for more detail &lt;a href=&quot;https://t.co/WoIvUvoKhw&quot;&gt;https://medium.com/@boneh/using-zk-proofs-to-fight-disinformation-17e7d57fe52f…&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You use Adobe Photoshop to add your brother to the image. Adobe summarizes the transformations you performed to get from the PNG to the PNG with your brother, and adds them to the C2PA record when you save the image.&lt;/p&gt;

&lt;p&gt;You put the image into a TikTok or share it on Twitter. These interfaces display the C2PA record of your image, probably in a format with highly simplified UX that only reveals the relevant information to the user: this is a real image, with some substantial changes to the content in Photoshop.&lt;/p&gt;

&lt;p&gt;Another creator stitches or quote-tweets your image. C2PA credentials may have additions (with stitches) or may just be displayed as a stack of credentials.&lt;/p&gt;
&lt;h3 id=&quot;moat-noat-for-you&quot;&gt;Moat? Noat for you.&lt;/h3&gt;
&lt;p&gt;Eventually, C2PA could become like HTTPS, where the lock in the browser eventually goes away to be replaced with scary warnings when the proper certifications are not present.&lt;/p&gt;

&lt;p&gt;So- this all seems pretty opt-in, which is great for C2PA taking over the world, and less great for moat of a business attempting to make money off of being a C2PA protocol.&lt;/p&gt;

&lt;p&gt;It also looks like everyone who matters in terms of relevant market share is in, except maybe Apple who is probably doing some bitchy uncompetitive shenanigans in the background. This is not great for a startup trying to promote a competing standard or introduce a new solution with any sort of moat at all.&lt;/p&gt;
&lt;h3 id=&quot;where-can-a-blockchain-fit-in&quot;&gt;Where can a blockchain fit in?&lt;/h3&gt;
&lt;h4 id=&quot;q1-you-mentioned-zk-earlier-what-about-all-our-zk-tech&quot;&gt;Q1. You mentioned ZK earlier. What about all our ZK tech?&lt;/h4&gt;
&lt;p&gt;A1: Nobody in the real world will care about the security difference between ZK and SGX until it’s incredibly fast. And probably not even then. SGX is practical and safe enough for now.&lt;/p&gt;

&lt;p&gt;Simple transformations like resizing an image (like that Dan Boneh paper above) are one thing, and ZK proving these is still not at an appropriate speed for these applications. genAI image editing workflows are getting popular, and even if you assume the generative parts of the editing flow are just signed with OpenAI’s keys instead of proven, it’s still just laughably complex and slow to prove right now.&lt;/p&gt;

&lt;p&gt;Anyway, a few companies here in blockchain land have the runway to maybe survive until ZK GTM is practical (if they’re wise with their obscenely large VC rounds), but I’m not entirely sold that ZK will &lt;em&gt;ever&lt;/em&gt; be practical for this. There is a lower bound on the computational complexity of ZK proving a computation that is strictly greater than the complexity of the origin computation, and image/video editing flows are the meatiest possible compute workloads that ever happen at the edge… so this is one of the last places I’d expect to see ZK market successes.&lt;/p&gt;

&lt;h4 id=&quot;q2-timestamping-a-blockchain-proves-that-something-existed-at-a-point-in-time-you-could-sign-a-hash-of-the-c2pa-and-put-it-on-chain-so-everyone-can-see-everything&quot;&gt;Q2: Timestamping? A blockchain proves that something existed at a point in time. You could sign a hash of the C2PA! And put it on chain so everyone can see everything!&lt;/h4&gt;
&lt;p&gt;A2 (bear/devil’s advocacy): What normal person doesn’t trust an MPC run by Google, Microsoft, a nation-state, and Intel, all signing and broadcasting timestamps?&lt;/p&gt;

&lt;p&gt;A2 (less bear, and what I actually believe): See &lt;a href=&quot;https://t.co/h49XE9eUJu&quot;&gt;https://opentimestamps.org&lt;/a&gt;. This could be sped up over using Bitcoin. Writing a hash to Ethereum costs thousandths of a cent. You’d want to merkleize the hashes to compress them and bring down the cost per hash. Honestly, there might be something here, the amount of content being produced is absolutely staggering. You’d need a shortish block time, but ten seconds would probably be plenty, and you don’t need much capacity if you merkleize. Ethereum could handle this.&lt;/p&gt;

&lt;p&gt;However, note the presence of Polygon on the C2PA website. This is CERTAINLY what they’re doing… I’m not bullish on a startup for getting this right and pulling the BD off, because you’d need to embed a blockchain client on every device.&lt;/p&gt;

&lt;p&gt;Unfortunately, I think the only place that value will reliably accrue for this one is gas fees, and maybe a sequencer-esque moat for the merkleization (but there could be multiple competing sequencers posting these timestamps to the same contract. so just kidding, no moat here).&lt;/p&gt;
&lt;h4 id=&quot;q3-decentralized-storage-our-fave&quot;&gt;Q3: Decentralized STORAGE!??!? Our FAVE?!?&lt;/h4&gt;
&lt;p&gt;A3: I am sorry to be the bearer of bad news. Timestamping/publishing anything more than the proof of time-locked existence of the hash of (data + certificate chain) is unnecessary. Keeping the certificate chain publicly available is only useful when the data needs to be publicly available. This is a small percentage of all data, and the vast majority of use cases are happy to serve the data and its C2PA log from S3.&lt;/p&gt;
&lt;h4 id=&quot;q4-decentralized-compute-that-does-verified-transformations-like-rendering-generation-or-transcoding-over-the-data-and-perhaps-even-signs-off-on-it-in-an-mpc-context&quot;&gt;Q4: Decentralized compute that does verified transformations (like rendering, generation, or transcoding) over the data and perhaps even signs off on it in an MPC context?&lt;/h4&gt;
&lt;p&gt;A4: You can spend your one precious life attempting to get PMF with this, but I will not be doing so. Most users’ security models will be quite pleased with the semi-centralized guarantees they get with signatures from OpenAI and AWS. The comparable efficiency of getting tasks accomplished in the workplace will be even more delight-inspiring.&lt;/p&gt;
&lt;h4 id=&quot;q5-decentralized-attestation-networks-like-decentralized-community-notes&quot;&gt;Q5: Decentralized attestation networks? Like decentralized community notes?&lt;/h4&gt;
&lt;p&gt;A5: Again, mostly quite bearish. As you see in the workflow above, most data that needs to be attested is generated as the content is generated or transformed, which means that the user will do it locally. This means there won’t be much of a market for decentralized validation- there’s not much information for parties outside the supply chain to add, so there’s nowhere for a protocol to insert itself. The two slivers of exception might be:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;location: absolutely needs an external validator, easy to forge without the right protocol design, is possible to do securely, would need to rely on in-camera SGX + onboard clocks with monotonicity guarantees that only sign at photograph-time. this is the use case of FOAM network, which one of you degenerate token fiend Value Adders should really fund, damn it.
    &lt;ul&gt;
      &lt;li&gt;rating: could probably make money with really freaking good GTM&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;decentralized community notes across the entire internet for attestations that can only be made by a real human: I think one of the media focused or NGO C2PA members is basically guaranteed to regulatory-capture this one. creds to &lt;a href=&quot;https://twitter.com/mattigags&quot;&gt;@mattigags&lt;/a&gt; though for coming up with it.
    &lt;ul&gt;
      &lt;li&gt;rating: only investable if the team has deep state/NGO/media/C2PA/social media connections, which very few of us web3 clowns possess&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Everyone here has done a bunch of yelling about Blockchain And AI!!! AI safety is finally our time to shine! Oh my god!!!!!!! We found a real use case!!!!&lt;/p&gt;

&lt;p&gt;To this I say: Hmm… maybe! If we have good GTM and execute. But… calm down, this is probably not a big enough wave to return your underwater fund.&lt;/p&gt;

&lt;p&gt;Unfortunately: unless your name is Jaynti Kanani, I think the probability that you GMI off of this narrative is vanishingly small.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Coindesk Decentralized Cloud Op-ed</title>
   <link href="https://w.laudiacay.cool/2024/04/16/coindesk-decentralized-cloud-oped.html"/>
   <updated>2024-04-16T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2024/04/16/coindesk-decentralized-cloud-oped</id>
   <content type="html">&lt;p&gt;This is an op-ed about the current problems, and future promise, of the industry my startup is operating in.&lt;/p&gt;

&lt;p&gt;It’s in CoinDesk. Read it &lt;a href=&quot;https://www.coindesk.com/consensus-magazine/2024/04/16/what-the-history-of-linux-says-about-the-long-road-to-decentralized-storage-adoption/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Enterprise PMF for Filecoin talk</title>
   <link href="https://w.laudiacay.cool/2023/09/04/filecoin-reykjavik-talk.html"/>
   <updated>2023-09-04T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2023/09/04/filecoin-reykjavik-talk</id>
   <content type="html">&lt;p&gt;I gave a talk at Fildev Reykjavik in September 2023 about why Filecoin doesn’t have product-market fit, the steps necessary to get there, and how my company attempts to make the network work. Based on market and product research conducted at Banyan.&lt;/p&gt;

&lt;p&gt;Watch it &lt;a href=&quot;https://youtu.be/uU96bIyruwo&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Side zk work</title>
   <link href="https://w.laudiacay.cool/2023/08/10/barustenberg.html"/>
   <updated>2023-08-10T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2023/08/10/barustenberg</id>
   <content type="html">&lt;p&gt;While I was at Zuzalu, I got pretty into writing Rust code for ZK / specifically folding.&lt;/p&gt;

&lt;p&gt;I worked with Lev Soukhanov on implementing his “folding endgame” &lt;a href=&quot;https://github.com/levs57/Moon-Moon&quot;&gt;here&lt;/a&gt;. This design allows folded ZK circuit steps to pass verified information around without expensive lookup gates, memory accesses, or adding other state to verify to a ZKVM. You “leak” part of the witness and pass it around, then do a consistency check on the reads and writes from the “leaked witness bits”. It’s a modification to the Nova codebase.&lt;/p&gt;

&lt;p&gt;I worked on and community-managed contributions to a Rust rewrite of Aztec’s Barretenberg &lt;a href=&quot;https://github.com/laudiacay/barustenberg&quot;&gt;here&lt;/a&gt; for a while afterwards.&lt;/p&gt;

&lt;p&gt;Also see my post about p1nch.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Trustless CDN Design</title>
   <link href="https://w.laudiacay.cool/2023/04/17/trustless-CDN.html"/>
   <updated>2023-04-17T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2023/04/17/trustless-CDN</id>
   <content type="html">&lt;p&gt;I gave a talk about good design and game theory for a trustless CDN at the HTTP Gateways track of IPFS Thing in Brussels, Belgium.&lt;/p&gt;

&lt;p&gt;The PPTX is &lt;a href=&quot;/assets/files/ipfs-cdn-incentives.pptx&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check out the speaker notes.&lt;/p&gt;

&lt;p&gt;Matt Stephenson from Pantera formalized some of the peer-to-peer game theory &lt;a href=&quot;https://gist.github.com/laudiacay/3e082a234e3424701b38f10ef174e720&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We haven’t built this because it making money would depend on the demand side. Which currently doesn’t exist. You have to get popular apps on (or built on) it. Good luck, nobody so far has succeeded, millions of venture capital dollars have gone into this hole.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>P1nch</title>
   <link href="https://w.laudiacay.cool/2023/03/05/p1nch.html"/>
   <updated>2023-03-05T00:00:00+00:00</updated>
   <id>https://w.laudiacay.cool/2023/03/05/p1nch</id>
   <content type="html">&lt;p&gt;We (Lev Stambler and I) wrote a cool little batched-private-defi-execution app for Ethereum with Lev Stambler for the Zuzalu ZK hackathon.&lt;/p&gt;

&lt;p&gt;The concept is like Tornado Cash but for swapping. It’s built something like Penumbra minus the homomorphic shielding (thanks to Henry de Valence for input on this aspect of the design!), and it’s also something like ZCash but with an added “swap” transaction type.&lt;/p&gt;

&lt;p&gt;It is not done, absolutely unaudited, do not use this. I mostly focused on the sequencer and the solidity, he wrote the Circom, and we co-created the design.&lt;/p&gt;

&lt;p&gt;Check out the GitHub &lt;a href=&quot;https://github.com/laudiacay/p1nch/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 

</feed>