<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on John Wang</title><link>https://johnjwang.com/post/</link><description>Personal website of John Wang - previously co-founder / CTO of Assembled and an early engineer at Stripe. Writing about AI, engineering, and startups.</description><generator>Hugo</generator><language>en-us</language><webMaster>johnjianwang@johnjwang.com (John Wang)</webMaster><lastBuildDate>Fri, 25 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://johnjwang.com/post/" rel="self" type="application/rss+xml"/><item><title>How X's ranking algorithm works</title><link>https://johnjwang.com/post/2026/09/25/how-xs-ranking-algorithm-works/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/09/25/how-xs-ranking-algorithm-works/</guid><description>&lt;p>There&amp;rsquo;s a ton of folk wisdom on X about how to go viral. A few examples you&amp;rsquo;ll see over and over:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Put links in the first reply instead of the post.&lt;/strong> &amp;quot; (&lt;a href="https://sproutsocial.com/insights/twitter-algorithm/">Sprout Social&lt;/a>).&lt;/li>
&lt;li>&lt;strong>Replies are king.&lt;/strong> &amp;ldquo;A reply on your tweet is worth 13.5x a like,&amp;rdquo; and if you reply back, &amp;ldquo;a two-way conversation [is] worth 150x more than a single like&amp;rdquo; (&lt;a href="https://opentweet.io/blog/x-algorithm-secrets-2026">OpenTweet&lt;/a>).&lt;/li>
&lt;li>&lt;strong>Pay for Premium.&lt;/strong> Premium gets &amp;ldquo;roughly 4x for in-network reach to your own followers and about 2x for out-of-network reach to non-followers&amp;rdquo; (&lt;a href="https://socialrails.com/blog/how-to-grow-on-twitter-x-complete-guide">SocialRails&lt;/a>).&lt;/li>
&lt;/ul>
&lt;p>But it&amp;rsquo;s very hard to tell what&amp;rsquo;s real, and most of it traces back to code Twitter released in 2023. But X now publishes the production code for its &amp;ldquo;For You&amp;rdquo; feed at &lt;a href="https://github.com/xai-org/x-algorithm">xai-org/x-algorithm&lt;/a> (including the ranking weights!) and they update it about every four weeks.&lt;/p>
&lt;h2 id="how-the-ranker-works">How the ranker works&lt;/h2>
&lt;p>The basic trick of the ranking algorithm is to use something cheap to narrow the available options, then save the expensive model for a few thousand posts.&lt;/p>
&lt;figure style="max-width:600px;margin:1.5rem auto;">
&lt;img src="https://johnjwang.com/images/x-pipeline.svg" alt="How X's ranker works. Index: Grok and Gemma LLMs read the post and preprocess it, and it becomes a six-number semantic ID. Retrieve: filter down from about 10 million posts to about 2,800, the nearest to your history and interests plus posts from people you follow. Rank: the Phoenix transformer scores each post by its predicted actions, as the sum of weight times the probability of about 25 actions." width="600" style="display:block;width:100%;height:auto;margin:0;">
&lt;figcaption style="margin-top:0.45rem;font-size:0.8em;line-height:1.45;color:#666;text-align:center;">Source: &lt;a href="https://github.com/xai-org/x-algorithm">xai-org/x-algorithm&lt;/a>, September 2026 release.&lt;/figcaption>
&lt;/figure>
&lt;ol>
&lt;li>&lt;strong>Retrieval narrows ~10 million posts to ~2,800.&lt;/strong> Most come from people you follow or from an embedding search for posts close to your recent history.&lt;/li>
&lt;li>&lt;strong>A transformer predicts what you&amp;rsquo;ll do.&lt;/strong> Phoenix (whose code started as a port of Grok-1) reads your last ~1,000 actions and predicts the odds you&amp;rsquo;ll like, reply, share, mute, or report each post.&lt;/li>
&lt;li>&lt;strong>A weighted sum becomes the score.&lt;/strong> Posts from people you don&amp;rsquo;t follow get multiplied by 0.75, and each extra post from the same author counts for less.&lt;/li>
&lt;/ol>
&lt;p>A few implementation details I found fascinating:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>The ranker never reads your words.&lt;/strong> Its inputs are post IDs, author IDs, and actions. Your text only gets in through a &lt;em>semantic ID&lt;/em> (basically think of it like a small embedding): six numbers from 0 to 255. The first number picks one of 256 broad neighborhoods, and each number after that narrows it down further. Posts on the same topic end up sharing the first few numbers.&lt;/li>
&lt;li>&lt;strong>An LLM also writes a report on every post.&lt;/strong> A Gemma-based initial filter (called, hilariously, the &amp;ldquo;banger initial screen&amp;rdquo;) reads each post and outputs a description, tags, topic categories, yes/no flags like high quality, spam, and NSFW, and a &amp;ldquo;slop score.&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>The weights are in &lt;a href="https://github.com/xai-org/x-algorithm/blob/main/home-mixer/params/param.rs">&lt;code>param.rs&lt;/code>&lt;/a>.&lt;/strong> A Copy-link share is incredibly valuable and worth a multiplier of 20, a reply is worth 5 (not 13.5 as past articles noted), quote 5, DM share 5, repost 1, and like 0.5. Getting reported is −234 and muting is −58.8 (so incredibly bad). Though note that these are based on &lt;em>probabilities&lt;/em> of actions, not actual actions themselves.&lt;/li>
&lt;li>&lt;strong>A lot of the folk wisdom isn&amp;rsquo;t in the code.&lt;/strong> There&amp;rsquo;s no weight for the author replying back, and I couldn&amp;rsquo;t find a Premium multiplier anywhere in the scoring code.&lt;/li>
&lt;li>&lt;strong>Mutual follows got a big boost this summer.&lt;/strong> Replies on original posts from mutual follows now count for 20 instead of 5 (X even published the &lt;a href="https://github.com/xai-org/x-algorithm/blob/main/docs/BIDIRECTIONAL_BOOST_CHANGE.md">whole A/B test history&lt;/a>, which is pretty cool to see).&lt;/li>
&lt;/ul>
&lt;figure style="max-width:600px;margin:1.5rem auto;">
&lt;img src="https://johnjwang.com/images/x-weights.svg" alt="What each action is worth on X, as a multiplier on the predicted probability of each action: copy-link share 20, reply 5, quote 5, DM share 5, follow the author 4, repost 1, like 0.5, report minus 234, mute minus 58.8, not interested minus 43.2, block minus 31.2." width="600" style="display:block;width:100%;height:auto;margin:0;">
&lt;/figure>
&lt;h2 id="what-this-means-for-your-posts">What this means for your posts&lt;/h2>
&lt;p>So what should you actually do?&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Write things people send around.&lt;/strong> A copy-link share carries 40 times the weight of a like, which makes it incredibly valuable. People generally tend to forward useful things like a surprising number, a clear chart, or an explanation that breaks something down simply.&lt;/li>
&lt;li>&lt;strong>Start conversations.&lt;/strong> Replies and quotes each carry 10 times the weight of a like. Build mutual follows with people in your field, since their replies count four times as much.&lt;/li>
&lt;li>&lt;strong>Stay on topic.&lt;/strong> To reach people who don&amp;rsquo;t follow you, your post has to land near their interests in embedding space. A post clearly about one thing gets a clear semantic ID.&lt;/li>
&lt;li>&lt;strong>Don&amp;rsquo;t rage bait.&lt;/strong> Mutes and reports are by far the heaviest negative weights, so it&amp;rsquo;s not really in your interest to post baity content.&lt;/li>
&lt;li>&lt;strong>Post less, but better.&lt;/strong> Your second post in someone&amp;rsquo;s feed counts at about 0.6x, and your third about 0.4x.&lt;/li>
&lt;li>&lt;strong>Everything expires in 48 hours.&lt;/strong> The ranker stops considering older posts, so there&amp;rsquo;s definitely a timing element of a post and might make weekend vs weekday timing important (though how time plays a factor depends on viewing and posting distributions, which aren&amp;rsquo;t available in the code itself).&lt;/li>
&lt;li>&lt;strong>Links are fine now.&lt;/strong> X &lt;a href="https://www.freepressjournal.in/tech/x-product-head-nikita-bier-confirms-link-penalty-removed-over-a-year-ago-tells-mark-zuckerberg-he-can-post-them-directly">says the link penalty ended in mid-2025&lt;/a>, and the code agrees. Just make sure the post stands on its own.&lt;/li>
&lt;/ol>
&lt;p>There are still some things we don&amp;rsquo;t know, though. The trained model isn&amp;rsquo;t public and every score is personalized to the viewer, so you can&amp;rsquo;t compute ahead of time how a post will do, but it is pretty intersting to get this level of transparency on the algorithm.&lt;/p></description></item><item><title>Megafauna extinction and startups</title><link>https://johnjwang.com/post/2026/09/23/megafauna-extinction-and-startups/</link><pubDate>Wed, 23 Sep 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/09/23/megafauna-extinction-and-startups/</guid><description>&lt;p>I was recently in Alaska and saw a massive moose, probably the biggest animal I&amp;rsquo;d ever seen in person. It got me down a rabbit hole as to why moose are so big, which eventually led me into a fascinating story of evolution and extinction that seems particularly relevant to startups in the age of LLMs.&lt;/p>
&lt;h2 id="why-being-big-wins">Why being big wins&lt;/h2>
&lt;p>There seem to be 4 main reasons why moose are so large:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Surface area to volume ratio for cold winters.&lt;/strong> Moose live in very cold regions that have particularly harsh winters. Because of that, the ability to conserve body heat is very important. Surface area to volume ratio works in favor of large bodies here: surface area is generally a square of your dimensions and volume is a cube, so as your dimensions grow, the amount of surface area for heat to escape shrinks compared to your overall mass. This means that larger bodied animals are more adept at retaining heat (the same reasoning works the other way for why you want smaller bodies for long distance runners to allow heat to escape more easily).&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://en.wikipedia.org/wiki/Kleiber%27s_law">Kleiber&amp;rsquo;s Law&lt;/a> $BMR \propto M^{0.75}$.&lt;/strong> Swiss biologist Max Kleiber found in the 1930s that the basal metabolic rate (the energy expenditure of an animal) generally tends to scale to the 3/4 power of an animal&amp;rsquo;s mass. This means that if an animal gets 100 times larger, then the amount of calories the animal needs to consume only increases by 32 times. So larger animals tend to be more efficient. If there&amp;rsquo;s enough food available, then a larger animal will tend to use calories more effectively than a smaller one.&lt;/li>
&lt;li>&lt;strong>Size makes predation much harder.&lt;/strong> Adult moose are so big that they have almost no natural predators. Even those predators like wolves or bears who do attack them very much prefer to attack babies or injured / old moose. Adult bull moose are very large and have very strong, long legs that can kill a wolf with a good strike, so bears/wolves tend to rely on surprise and prey on weakened moose.&lt;/li>
&lt;li>&lt;strong>Energy reserves.&lt;/strong> The larger you are, the more energy you can carry on your body in the form of fat. This is particularly useful for climates moose live in, which swing wildly from abundance in the spring and summer months to barrenness in the winter months. It&amp;rsquo;s also generally helpful for making you more robust to environmental changes.&lt;/li>
&lt;/ol>
&lt;iframe src="https://johnjwang.com/diagrams/megafauna-kleiber.html" title="Interactive: megafauna to scale, filled by the energy they burn at rest under Kleiber's law" loading="lazy" width="100%" height="620" style="display:block;border:1px solid #dfe5e7;border-radius:12px;margin:1.5rem 0;width:100%;">&lt;/iframe>
&lt;p>Interestingly, reasons 2-4 apply to most animals and aren&amp;rsquo;t specific to moose or their arctic habitat. That leads to the next observation. Instead of asking why moose are so large, the opposite question might be more useful: why are there so few large animals?&lt;/p>
&lt;h2 id="megafauna-and-mega-extinction">Megafauna and mega-extinction&lt;/h2>
&lt;p>In fact, there used to be a lot more throughout history, and scientists even had a name for them: &lt;strong>megafauna&lt;/strong>. There&amp;rsquo;s even a name for the pattern, &lt;a href="https://en.wikipedia.org/wiki/Cope%27s_rule">Cope&amp;rsquo;s rule&lt;/a>, which says that lineages tend to get larger over time.&lt;/p>
&lt;ul>
&lt;li>Irish elk: a deer the size of a moose with antlers spanning 12 feet.&lt;/li>
&lt;li>Woolly mammoth: 6 tons, roughly the size of an African elephant.&lt;/li>
&lt;li>Giant ground sloth (Megatherium): a 4-ton sloth that stood taller than an elephant when it reared up.&lt;/li>
&lt;/ul>
&lt;p>However, most of them suddenly went extinct in the last 50,000 years. Of the 57 species of herbivore over 1,000 kg that were alive then, &lt;a href="https://www.cambridge.org/core/journals/cambridge-prisms-extinction/article/latequaternary-megafauna-extinctions-patterns-causes-ecological-consequences-and-implications-for-ecosystem-management-in-the-anthropocene/E885D8C5C90424254C1C75A61DE9D087">only 11 survive today&lt;/a>. In North America, the average land mammal &lt;a href="https://www.science.org/doi/10.1126/science.aao5987">shrank by more than 10x&lt;/a>. We still have some megafauna (elephants, giraffes, moose), but most animals are now much smaller.&lt;/p>
&lt;p>Though there were decades of debate about what caused these extinctions (particularly whether climate change had an impact), scientists now generally accept that humans were the cause. These animals had survived &lt;a href="https://www.cambridge.org/core/journals/cambridge-prisms-extinction/article/latequaternary-megafauna-extinctions-patterns-causes-ecological-consequences-and-implications-for-ecosystem-management-in-the-anthropocene/E885D8C5C90424254C1C75A61DE9D087">more than twenty glacial cycles&lt;/a> over the previous two million years, and the last one was only different in that humans had arrived on the scene. A &lt;a href="https://www.nature.com/articles/s41467-023-43426-5">2023 study&lt;/a> reconstructed the population histories of 139 living megafauna species from their genomes and found that 91% of them started declining between 32,000 and 76,000 years ago, on every continent, and almost exactly tracking the spread of humans. Total megafauna biomass on Earth fell by 92%. The only place the giants held on was Africa, where they&amp;rsquo;d had a couple million years to get used to us.&lt;/p>
&lt;p>Megafauna are perfect for humans: they&amp;rsquo;re huge, and you only need to hunt one to have enough calories to survive for a very long time. The problem though is that you don&amp;rsquo;t need a huge amount of hunting in order to kill off a megafauna species, especially if the species reproduces really slowly.&lt;/p>
&lt;h2 id="going-extinct-but-gradually">Going extinct, but gradually&lt;/h2>
&lt;p>So how did humans kill off so many species of megafauna, especially given the relatively small human populations at the time?&lt;/p>
&lt;p>Well, when you &lt;a href="https://royalsocietypublishing.org/rspb/article-abstract/269/1506/2221/71629/Determinants-of-loss-of-mammal-species-during-the?redirectedFrom=fulltext">control for body size&lt;/a>, reproductive rate has a massive impact on potential extinction probability. Species producing one or fewer offspring per female per year had more than 50% odds of dying out, regardless of size. You just need:&lt;/p>
$$r_{birth} &lt; r_{death} + r_{hunting}$$
&lt;p>If a species is held slightly below replacement for a long time, you get extinction over time.&lt;/p>
&lt;p>For a fast breeder (think rabbits or mice), $r_{birth}$ is huge and it takes an enormous amount of hunting to flip the inequality. For a mammoth, gestation was &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/S1040618211003259">about 22 months&lt;/a>, females didn&amp;rsquo;t mature until 10 to 12, and after that they had &lt;a href="https://deepblue.lib.umich.edu/handle/2027.42/143902?show=full">one calf every 3 to 6 years&lt;/a>. This means a few percent of extra mortality a year is all it takes for extinction. You actually don&amp;rsquo;t have to hunt a species to zero.&lt;/p>
&lt;p>When Polynesians arrived in New Zealand, the moa (a 500-pound flightless bird with no natural predators) was &lt;a href="https://www.nature.com/articles/ncomms6436">gone within about a century&lt;/a>. The human population at the time was under 2,000 people, roughly one person per 100 square kilometers. There wasn&amp;rsquo;t any industrial hunting or big-game culture, but there was just enough persistent drag on a species that couldn&amp;rsquo;t breed quickly.&lt;/p>
&lt;p>The interesting thing is that some of these species lived for thousands of years while $r_{birth} &lt; r_{death} + r_{hunting}$. For example, though mainland mammoths were killed off by about 10,000 years ago, there still existed a small group of mammoths that survived on Wrangel Island in the Arctic Ocean &lt;a href="https://www.cell.com/cell/fulltext/S0092-8674(24)00577-4">until about 4,000 years ago&lt;/a>. There were only a few hundred of them living for millennia. We have parallel examples of this with &lt;a href="https://en.wikipedia.org/wiki/Megalocnus">Caribbean ground sloths&lt;/a>, where island populations lasted another 4,000 to 6,000 years after the mainland animals were gone, and &lt;a href="https://en.wikipedia.org/wiki/Steller%27s_sea_cow">Steller&amp;rsquo;s sea cow&lt;/a>, which vanished across most of the North Pacific and then hung on as a Commander Islands remnant until the last animals were killed in 1768.&lt;/p>
&lt;p>There&amp;rsquo;s a distinction here between dead and extinct. A species is functionally dead when it&amp;rsquo;s held below replacement with no way back (like the mammoths on Wrangel Island), even if the last individual doesn&amp;rsquo;t die for thousands of years.&lt;/p>
&lt;h2 id="what-thrived-afterwards">What thrived afterwards&lt;/h2>
&lt;p>As the megafauna died off, it opened up the world for other species to thrive. As Aristotle said, &amp;ldquo;nature abhors a vacuum&amp;rdquo; and there was plenty of opportunity as changes in the environment allowed for new winners, typically employing one of three strategies:&lt;/p>
&lt;h3 id="strategy-generalist-rats-pigs">Strategy: Generalist (Rats, Pigs)&lt;/h3>
&lt;p>The first and most common strategy was to be a generalist. Species employing this strategy would eat whatever is around, live wherever there&amp;rsquo;s shelter, and breed faster than anything could kill them.&lt;/p>
&lt;p>Rats are the clearest case. They were perfectly set up to take advantage of human proliferation, as humans made much more of the habitat that rats love. They&amp;rsquo;re more than happy living in ships, sewers, grain stores, or apartment walls. As humans built up cities, rats found an environment that was incredibly hospitable because of their ability to eat human scraps.&lt;/p>
&lt;p>Another key element of the generalist strategy is fast reproduction. Rats have a &lt;a href="https://animaldiversity.org/accounts/Rattus_norvegicus/">gestation period of about three weeks&lt;/a> and a female can produce dozens of young a year. This turnover rate means you can hunt rats continuously and still fail to push them below replacement (just look at what happened to New York &lt;a href="https://www.theguardian.com/us-news/2025/sep/24/new-york-city-rat-czar-kathleen-corradi-eric-adams">Rat Czar&lt;/a>).&lt;/p>
&lt;h3 id="strategy-adapt-coyotes-raccoons-crows">Strategy: Adapt (Coyotes, Raccoons, Crows)&lt;/h3>
&lt;p>The second winning strategy was rarer, because relatively few species were able to pull it off. The strategy was adaptation: as the world changed, these animals changed with it by adjusting their diets, habitats, and behaviors.&lt;/p>
&lt;p>Coyotes are the most well-known example of this. Before Europeans remade North America, they were mostly a western prairie animal. As wolves disappeared and forests were cleared, coyotes adapted to be able to live in close proximity to cities. Their social structure became flexible, as they can either hunt alone or in pairs when prey is small, or form loose family groups when they need to take on larger animals. In cities, they flip their schedule and go mostly nocturnal to avoid people and move quickly through developed blocks at night. They live in the leftover green areas like parks, golf courses, and railroad corridors.&lt;/p>
&lt;p>Their diet also changed. They prefer rodents and rabbits (things you would find on the prairie), but switch to fruit, pet food, and garbage when rodents aren&amp;rsquo;t available. They changed their hunting and feeding patterns to take advantage of the human food in cities. This flexibility means they&amp;rsquo;re now everywhere and have migrated to every US state except Hawaii.&lt;/p>
&lt;h3 id="strategy-partner-dogs-cows-chickens-sheep">Strategy: Partner (Dogs, Cows, Chickens, Sheep)&lt;/h3>
&lt;p>The final winning strategy was to partner, basically &amp;ldquo;if you can&amp;rsquo;t beat them, join them.&amp;rdquo; Species that chose this strategy stopped competing with humans and survived by becoming useful to us.&lt;/p>
&lt;p>Many animals hit upon this strategy, but dogs are famously good at it. They were originally wolves, but became hunting partners and companions instead of rivals. They&amp;rsquo;re now everywhere and there are literally &lt;a href="https://blog.oup.com/2014/03/one-billion-dogs-wildlife-conservation/">a billion of them&lt;/a>. The wolves that didn&amp;rsquo;t take the deal still exist, but they&amp;rsquo;re far less numerous (scientists estimate there are around &lt;a href="https://en.wikipedia.org/wiki/Gray_wolf_population_by_country">200-250k gray wolves in the world&lt;/a>).&lt;/p>
&lt;p>This strategy comes with tradeoffs though: dogs are no longer fierce predators, and while there are billions of cows and chickens, their existence isn&amp;rsquo;t particularly happy. Also, most of them can&amp;rsquo;t survive outside the human farming system. Partnership is a good way to thrive, but it&amp;rsquo;s also how you lose control of your future.&lt;/p>
&lt;h2 id="megafauna-and-startups">Megafauna and startups&lt;/h2>
&lt;p>I&amp;rsquo;m particularly fascinated by the megafauna extinction because I think you can compare the introduction of humans in evolutionary history to the arrival of LLMs in the tech world.&lt;/p>
&lt;p>There are quite a lot of similarities:&lt;/p>
&lt;ul>
&lt;li>Before LLMs, it made sense to be as big as possible. Hiring engineers was how you shipped more, and also how you kept those engineers from becoming a competitor. Between &lt;a href="https://news.crunchbase.com/layoffs/analysis-big-tech-pandemic-amzn-meta/">2019 and 2022&lt;/a>, Amazon&amp;rsquo;s headcount rose 93%, Meta&amp;rsquo;s 92%, Alphabet&amp;rsquo;s 60%, and Microsoft&amp;rsquo;s 53%. Bigger teams were less efficient per person, but they were still the optimal choice for a climate where ecommerce and internet spend was increasing dramatically. The focus on hiring was a similar optimization to what the megafauna made as bigger generally means you can accomplish more and dominate in the environment you&amp;rsquo;re placed.&lt;/li>
&lt;li>The arrival of LLMs is similar to the arrival of humans: there was a massive shock to the system that
caused the landscape to change. Coding and many auxiliary functions which previously required armies of people got much cheaper and more efficient. Leverage from LLMs has made size-based defenses much less useful. In fact, the size of your company, which was once an asset, has now become a hindrance. Most AI native companies are far more efficient on a revenue per person basis and skew much smaller (see figure below).&lt;/li>
&lt;li>Incumbents didn&amp;rsquo;t immediately recognize that AI native companies were predators. Similar to dodos and the moa, they had never seen this kind of competitor before and they didn&amp;rsquo;t register as a threat. They were slowly losing the next dollar, but mainly focused on keeping their existing customer base. In 2025, &lt;a href="https://www.businessinsider.com/lexisnexis-thomson-reuters-legal-tech-new-era-ai-competition-2025-8">the head of LexisNexis North America said&lt;/a> he didn&amp;rsquo;t see the new legal AI startups as a serious threat. By then &lt;a href="https://www.cnbc.com/2025/08/04/legal-ai-startup-harvey-revenue.html">Harvey had reached $100 million a year&lt;/a> and was in &lt;a href="https://www.artificiallawyer.com/2025/08/04/harvey-reaches-100m-arr-42-of-amlaw-100/">42% of the AmLaw 100&lt;/a>.&lt;/li>
&lt;/ul>
&lt;iframe src="https://johnjwang.com/diagrams/megafauna-company-scaling.html" title="Interactive: revenue per employee against company size for SaaS companies at IPO, incumbents, and AI-native companies" loading="lazy" width="100%" height="600" style="display:block;border:1px solid #dfe5e7;border-radius:12px;margin:1.5rem 0;width:100%;">&lt;/iframe>
&lt;h2 id="zombie-megafauna">Zombie megafauna&lt;/h2>
&lt;p>Some of the megafauna are already visibly dying, but relatively few of them are extinct. Yes, there are examples like Chegg (its stock fell 40% after their &lt;a href="https://www.cnbc.com/2023/05/02/chegg-drops-more-than-40percent-after-saying-chatgpt-is-killing-its-business.html">CEO said ChatGPT was hurting new signups&lt;/a>) and Stack Overflow (new questions fell to &lt;a href="https://api.stackexchange.com/2.3/questions?site=stackoverflow&amp;amp;fromdate=1785542400&amp;amp;todate=1788220800&amp;amp;filter=total">about 1,100 in August 2026&lt;/a>, from a &lt;a href="https://ppc.land/stack-overflow-drops-to-1-442-questions-in-july-down-99-from-2014-peak/">peak of more than 200,000 in a month&lt;/a>). But in general, like in megafauna extinction, much of the technology ecosystem extinction is playing out more gradually and most incumbents are attempting to adapt.&lt;/p>
&lt;p>Nearly every company now has an AI strategy, an AI product, and an executive whose job is to make the company AI-native. So the interesting question is actually whether incumbents will adapt fast enough. A company&amp;rsquo;s population is its customers, and it shrinks for the same reason a species does:&lt;/p>
$$r_{new} &lt; r_{churn} + r_{competitor}$$
&lt;p>An incumbent can ship a perfectly good AI product and still lose if competitors are taking customers more quickly. A few things from the megafauna explain how that happens:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Predators adapt quickly.&lt;/strong> Megafauna could adapt, but their slow reproduction rate hindered them in comparison to faster reproducers. Humans adapted quickly by using culture and by spreading knowledge through spoken word between generations. Other winners reproduced on much faster cycles (e.g. rats every few weeks). Similarly, an incumbent&amp;rsquo;s AI strategy moving through annual planning and multiple layers of red tape can be outmaneuvered by a twenty-person startup that ships every week.&lt;/li>
&lt;li>&lt;strong>Predators take the calves.&lt;/strong> Bears don&amp;rsquo;t go after healthy adult moose, they go after the young, the old, and the sick. AI-native startups similarly won&amp;rsquo;t be ripping out existing contracts to start. They generally win the next customer, like Harvey did against LexisNexis. The existing customer base might look healthy, but a herd without calves is dying. And once the new species gets established, it&amp;rsquo;s very hard to dislodge.&lt;/li>
&lt;li>&lt;strong>Decline looks normal from the inside.&lt;/strong> A population shrinking 1% a year takes about 1,400 years to go from a million to zero. That&amp;rsquo;s instant from a geological standpoint, but basically invisible to anyone who&amp;rsquo;s living through it. Losing a few percentage points of growth each quarter doesn&amp;rsquo;t feel alarming for any particular quarter, but taken in aggregate can be catastrophic.&lt;/li>
&lt;li>&lt;strong>Most megafauna shrink.&lt;/strong> Plenty of megafauna species survived in much smaller populations and ranges (lions went from southern Europe, the Middle East, and most of Africa to &lt;a href="https://doi.org/10.7717/peerj.10504">scattered African populations&lt;/a>), and some physically shrank (modern bison are &lt;a href="https://doi.org/10.1002/ece3.4019">noticeably smaller than their Ice Age ancestors&lt;/a>). The likely outcome for most incumbents is to become a smaller company in a smaller niche, while its growth goes to someone new.&lt;/li>
&lt;/ul>
&lt;h2 id="winning-strategies-in-the-ai-era">Winning strategies in the AI era&lt;/h2>
&lt;p>The most interesting part to me though is who&amp;rsquo;s thriving. Each winning strategy since the LLM boom has parallels with evolutionary winning strategies. Generalists eat everything, adapters change what they eat, partners attach to the frontier labs, and new companies are born growing fast. Though, similar to animals, each strategy comes with its own tradeoffs.&lt;/p>
&lt;h3 id="strategy-generalist-tsmc-cloudflare-stripe-openrouter">Strategy: Generalist (TSMC, Cloudflare, Stripe, OpenRouter)&lt;/h3>
&lt;p>Rats didn&amp;rsquo;t win by being clever, they won by eating whatever humans left behind and living in whatever humans built. The generalists of the AI era do the same: they don&amp;rsquo;t need to pick which lab wins, because they thrive whenever more tokens flow through the system.&lt;/p>
&lt;p>TSMC fabs Nvidia&amp;rsquo;s GPUs, but also Google&amp;rsquo;s TPUs and Amazon&amp;rsquo;s Trainium chips, so they eat whenever the system increases total token spend. Cloudflare and Stripe are the backbone that handles the traffic and the payments. Every new AI app needs to sit behind a network and charge its customers, and every AI crawler and agent hitting the web runs through Cloudflare. OpenRouter routes requests to hundreds of models from nearly every lab. It doesn&amp;rsquo;t care which model wins, only that people keep sending tokens.&lt;/p>
&lt;p>The tradeoff is that generalists tend to grow with the tide, and shrink with it too when it goes the other direction.&lt;/p>
&lt;h3 id="strategy-adapt-cognition-intercom-baseten-handshake">Strategy: Adapt (Cognition, Intercom, Baseten, Handshake)&lt;/h3>
&lt;p>Coyotes kept what made them good (hunting skill, flexible packs) and changed their diet and schedule. The companies that have adapted well follow the same pattern of keeping a key asset and changing what they eat.&lt;/p>
&lt;ul>
&lt;li>Intercom kept its customers and support distribution, but rebuilt the company around their Fin AI agent. They started charging per resolution instead of per seat, cannibalizing their own pricing before someone else did it for them. They recently sold to Salesforce for &lt;a href="https://investor.salesforce.com/news/news-details/2026/Salesforce-Signs-Definitive-Agreement-to-Acquire-Fin/default.aspx">$3.6 billion&lt;/a>.&lt;/li>
&lt;li>Handshake had one of the biggest adaptations, going from a &lt;a href="https://joinhandshake.com/blog/our-team/introducing-handshake-ai/">college recruiting network&lt;/a> to a frontier lab data provider. They took their network of students and PhDs, but realized they could use that same network to train frontier models (and that this was &lt;a href="https://sacra.com/research/handshake-indeed-for-data-labelers/">much more lucrative&lt;/a>). They became &lt;a href="https://dealroom.co/news/127345-handshakes-arr-crosses-1b-as-ai-training-revenue-surges/">one of the first data companies&lt;/a> to reach &lt;a href="https://time.com/collection/time100-ai/2026/garrett-lord/">$1B in revenue&lt;/a>, against a huge amount of &lt;a href="https://www.upstartsmedia.com/p/handshake-refounding-layoff-ai">internal resistance&lt;/a>.&lt;/li>
&lt;li>Baseten started by doing ML infrastructure, but changed its customer from &lt;a href="https://techcrunch.com/2022/04/26/baseten-nabs-20m-to-make-it-easier-to-build-machine-learning-based-applications/">data scientists building apps&lt;/a> to &lt;a href="https://www.forbes.com/sites/kenrickcai/2024/03/04/baseten-series-b-making-ai-useful-inference/">LLM inference&lt;/a>. They&amp;rsquo;re now one of the fastest growing inference providers.&lt;/li>
&lt;/ul>
&lt;h3 id="strategy-partner-scale-ai-surge-ai-mercor">Strategy: Partner (Scale AI, Surge AI, Mercor)&lt;/h3>
&lt;p>These companies stopped competing with the frontier labs and made themselves useful to them instead by supplying the huge amounts of expert human data that labs need. By sheer mass, partnering is the most successful strategy there is: livestock now make up about &lt;a href="https://www.pnas.org/doi/10.1073/pnas.1711842115">60% of mammal biomass on Earth&lt;/a>, while wild mammals are about 4%.&lt;/p>
&lt;p>Data companies like Mercor, Surge, and Scale are making billions in revenue, but their growth rate isn&amp;rsquo;t independent. Chickens breed exactly as fast as humans want them to, and data vendors grow exactly as fast as the labs&amp;rsquo; data budgets.&lt;/p>
&lt;p>Another interesting parallel is seeing different sub-strategies. For example, dogs are valued for judgment and companionship, while chickens are interchangeable. This is similar to why Surge, reportedly &lt;a href="https://www.reuters.com/business/scale-ais-bigger-rival-surge-ai-seeks-up-1-billion-capital-raise-sources-say-2025-07-01/">selling expert judgment and highly curated data&lt;/a>, was able to pull ahead of Scale, which started as a &lt;a href="https://www.theverge.com/cs/features/831818/ai-mercor-handshake-scale-surge-staffing-companies">labeling body shop&lt;/a>.&lt;/p>
&lt;h3 id="strategy-start-fresh-cursor-cognition-harvey-elevenlabs-higgsfield">Strategy: Start fresh (Cursor, Cognition, Harvey, ElevenLabs, Higgsfield)&lt;/h3>
&lt;p>The last strategy is one that didn&amp;rsquo;t have time to develop after the megafauna extinction (we&amp;rsquo;re too early in evolutionary time), but has shown up after other extinctions. Survivors of mass extinction events go through &lt;a href="https://en.wikipedia.org/wiki/Adaptive_radiation">adaptive radiation&lt;/a> and rapidly diversify into all the niches that just opened up. After the dinosaurs died, mammals went from small nocturnal animals to whales, bats, and horses.&lt;/p>
&lt;p>Similarly, we&amp;rsquo;re seeing an explosion of new startups in niches that didn&amp;rsquo;t even exist a few years ago. AI code editors (Cursor), software factories (Cognition), legal AI (Harvey), voice AI (ElevenLabs), video AI (Higgsfield), and many more fields have suddenly opened up. Starting fresh has advantages in that you can shape yourself specifically to the new environment and there&amp;rsquo;s no mass to shed or old business to defend.&lt;/p>
&lt;p>That said, adaptive radiation is also incredibly wasteful. It produces a burst of new forms and most of them die out. Jasper was one of the first AI copywriting companies, and had raised &lt;a href="https://www.jasper.ai/blog/jasper-announces-125m-series-a-funding">$125 million&lt;/a> at a $1.5 billion valuation, when ChatGPT ate its niche. &lt;a href="https://www.forbes.com/sites/rashishrivastava/2024/04/23/the-prompt-the-latest-ai-startup-to-face-reality/">Tome&lt;/a> did the same thing with AI presentations. They had 20 million users, then completely pivoted and abandoned their product once Anthropic and OpenAI moved in.&lt;/p>
&lt;h2 id="which-animal-are-you">Which animal are you?&lt;/h2>
&lt;p>A huge environmental change just opened up a lot of niches, so whether you&amp;rsquo;re an existing company or starting something new, there&amp;rsquo;s a ton of opportunity. But remember that adaptive radiation is wasteful and most new species won&amp;rsquo;t make it.&lt;/p>
&lt;p>So, some interesting questions to ponder:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>What niche just opened?&lt;/strong> The best opportunities are things that weren&amp;rsquo;t possible (or weren&amp;rsquo;t economical) a couple of years ago. If the business could have been built in 2019, someone probably already occupies the niche.&lt;/li>
&lt;li>&lt;strong>How fast do you reproduce?&lt;/strong> How long does it take to go from idea to a high quality shipped product, and then to customers? If it&amp;rsquo;s measured in weeks, you&amp;rsquo;re built for this environment. If it&amp;rsquo;s still measured in quarters, you should take a look in the mirror.&lt;/li>
&lt;li>&lt;strong>Whose calves are you taking, and who&amp;rsquo;s taking yours?&lt;/strong> New companies don&amp;rsquo;t have to rip out an incumbent&amp;rsquo;s existing contracts. They can go after the next customer and the fringes of what incumbents make money from. If you&amp;rsquo;re the incumbent, is there a company winning the customers you would have won two years ago?&lt;/li>
&lt;li>&lt;strong>Are you a dog or a chicken?&lt;/strong> Almost every AI company depends on the frontier labs to some degree. That&amp;rsquo;s fine, as long as you add something meaningful that the labs can&amp;rsquo;t easily produce themselves.&lt;/li>
&lt;/ol>
&lt;p>Which brings me back to the moose I saw in Alaska. Moose aren&amp;rsquo;t the biggest animals that ever lived, or the fastest, or the strongest. But they made it through because they just happened to be built for the world that came next.&lt;/p>
&lt;p>The moose got lucky, but you get to choose.&lt;/p></description></item><item><title>The engineering behind the US Strategic Petroleum Reserve</title><link>https://johnjwang.com/post/2026/09/15/engineering-behind-us-strategic-petroleum-reserve/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/09/15/engineering-behind-us-strategic-petroleum-reserve/</guid><description>&lt;p>One of the most fascinating things I&amp;rsquo;ve learned about recently is the engineering behind the US Strategic Petroleum Reserve. Here are the key requirements it&amp;rsquo;s designed to meet:&lt;/p>
&lt;ul>
&lt;li>Store hundreds of millions of barrels of crude oil for long periods of time to &lt;a href="https://www.energy.gov/hgeo/opr/strategic-petroleum-reserve">respond to disruptions in petroleum supplies&lt;/a>.&lt;/li>
&lt;li>Keep the oil secure against attacks by our adversaries. This is an especially hard challenge because petroleum has this tendency to light on fire, so a huge concentration of it is especially difficult to keep safe.&lt;/li>
&lt;li>Release oil quickly so it can reach the market during a supply disruption.&lt;/li>
&lt;li>Keep maintenance costs low and last for decades.&lt;/li>
&lt;/ul>
&lt;p>The actual solution, like many great engineering solutions, is incredibly elegant and simple. But before we talk about it, let&amp;rsquo;s start with how you might go about solving this:&lt;/p>
&lt;h2 id="the-naive-solution-external-floating-roof-tanks">The naive solution: External floating roof tanks&lt;/h2>
&lt;figure style="max-width:480px;margin:1.5rem auto;">
&lt;img src="https://johnjwang.com/images/cushing-tank-farm.jpg" alt="A large storage tank with an exterior staircase at the Enbridge tank farm in Cushing, Oklahoma." width="480" style="display:block;width:100%;height:auto;margin:0;">
&lt;figcaption style="margin-top:0.45rem;font-size:0.8em;line-height:1.45;color:#666;">Enbridge tank farm, Cushing, Oklahoma, April 2010. Photo: &lt;a href="https://commons.wikimedia.org/wiki/File:Enbridge_tank_farm,_Cushing_OK.jpg">roy.luck&lt;/a>, &lt;a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0&lt;/a>.&lt;/figcaption>
&lt;/figure>
&lt;p>Looking at the requirements, the first thing most people would probably think to do is to just take what we do commercially for storing petroleum and scale it up. &lt;a href="https://en.wikipedia.org/wiki/External_floating_roof_tank">External floating roof tanks (EFRTs)&lt;/a> are the common solution for storing petroleum. Most tanks are confined to about 50 feet tall and 300 feet in diameter &amp;ndash; larger than that and you start to have engineering problems with the foundation and drainage systems. This gives a volume of $V = \pi (150 \mathrm{ft})^2(50 \mathrm{ft})$, or $3{,}532{,}500 \mathrm{ft}^3$, equivalent to about 630,000 barrels of oil.&lt;/p>
&lt;p>To hold 714 million barrels of oil (the full capacity of the Strategic Petroleum Reserve), you&amp;rsquo;d need about 1,130 of these tanks. If you use the standard capacity of the largest commercial petroleum farms (e.g., in Cushing, Oklahoma), you need about 45,000 acres to store these tanks. That&amp;rsquo;s basically the size of Washington, D.C., which means you&amp;rsquo;d need to acquire a lot of land.&lt;/p>
&lt;p>However, the biggest downside to using tanks is that they&amp;rsquo;re incredibly vulnerable to attack. Damage can cause spills and fires, and there&amp;rsquo;s a particular weak point at the seal between a floating roof and the tank shell. &lt;a href="https://law.resource.org/pub/us/cfr/ibr/002/api.2003.1998.pdf#page=38">Lightning-caused fires have been documented in the seal space of open floating-roof tanks&lt;/a>, so a deliberate ignition source (shrapnel, incendiary) could be particularly bad.&lt;/p>
&lt;h2 id="putting-tanks-underground">Putting tanks underground&lt;/h2>
&lt;p>Next up, one might think about putting the petroleum underground. The Navy actually did this at the &lt;a href="https://en.wikipedia.org/wiki/Red_Hill_Underground_Fuel_Storage_Facility">Red Hill Facility&lt;/a> near Pearl Harbor. Built in 1943, it housed 20 enormous steel-lined concrete tanks inside excavated volcanic rock. Each tank was about 100 feet across and 250 feet tall, making it comparable in volume to a large EFRT. Altogether, the facility housed 6 million barrels of fuel. The surrounding rock provided protection from aerial attack, which was a major reason for building the facility. But this was a substantial construction project, and thousands of workers had to excavate the tunnels, install steel liners, and pour concrete. The original construction cost was &lt;a href="https://ascelibrary.com/doi/abs/10.1061/JLADAH.LADR-1005">&lt;span class="no-math">$42.2 million (~$820M in 2026 dollars)&lt;/span>&lt;/a>.&lt;/p>
&lt;p>Also, groundwater protection became a major challenge. A tank released about 27,000 gallons of fuel in 2014. Separate releases in 2021 contaminated the Navy&amp;rsquo;s drinking-water system, causing the Navy to defuel and &lt;a href="https://www.epa.gov/red-hill/about-fuel-releases">permanently close the facility&lt;/a>.&lt;/p>
&lt;p>There&amp;rsquo;s also the question of scale. To get to 714 million barrels, you&amp;rsquo;d need roughly 119 Red Hill-sized facilities&amp;rsquo; worth of capacity and enough space to actually put these tanks in the ground. It would be an absolutely enormous construction project that would cost hundreds of billions of dollars (which, even for the government, is extremely expensive).&lt;/p>
&lt;h2 id="the-actual-solution-salt-caverns">The actual solution: Salt caverns&lt;/h2>
&lt;p>So how did the US solve this? The crux was using salt domes at four sites in Texas and Louisiana along the Gulf of Mexico. The US created massive caverns underground in these salt domes that hold about 10 million barrels each (more than the entire Red Hill facility). The DOE currently lists 60 caverns with a combined authorized storage capacity of about &lt;a href="https://www.energy.gov/hgeo/opr/spr-storage-sites">714 million barrels&lt;/a>.&lt;/p>
&lt;iframe src="https://johnjwang.com/diagrams/salt-cavern.html" title="Interactive salt cavern: create, store oil, and withdraw oil" loading="lazy" width="100%" height="850" style="display:block;border:1px solid #dfe5e7;border-radius:12px;margin:1.5rem 0;width:100%;">&lt;/iframe>
&lt;p>A few properties make this work:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Cylindrical caverns are excavated using water. Engineers drill into a salt dome and inject fresh water. The salt dissolves in the water, and then pumps are used to remove the resulting brine, leaving a cavern that can be used to store petroleum.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Salt contains the oil and helps seal small fractures. The rock salt surrounding the SPR&amp;rsquo;s caverns has extremely low permeability, meaning fluids have very little ability to pass through it. It also doesn&amp;rsquo;t react with petroleum. Under enormous pressures underground, salt also slowly deforms, which helps close small fractures. The salt itself can therefore contain the oil without a steel-and-concrete tank lining the cavern.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Oil floats on water, which means pumping water into the bottom of the cavern pushes the oil out. As fresh water is pumped into the bottom of the cavern, the oil gets displaced upwards into a delivery system.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>As a bonus, the location helps get oil to market. The Gulf Coast puts the reserve near refineries, pipelines, and marine terminals, which is particularly useful when the whole point is to deliver oil during a supply disruption.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>This storage solution is relatively inexpensive. DOE&amp;rsquo;s historical capital-cost estimate is about [$3.50 per barrel](https://www.energy.gov/hgeo/opr/spr-faqs) of cavern storage capacity, compared with &lt;span class="no-math">$15-$18&lt;/span> for aboveground tanks. Storing the oil deep underground also helps protect it from aerial attack.&lt;/p>
&lt;p>There are still tradeoffs, though. Creating caverns requires a water supply and a way to dispose of the brine. And fresh water introduced during withdrawals dissolves additional salt, gradually enlarging the caverns. That limits repeated cycling and makes cavern monitoring and maintenance quite important. The wells, pumps, and pipelines also need continued upkeep, so frequent withdrawals can degrade the infrastructure.&lt;/p></description></item><item><title>Why are there suddenly so many gambling companies?</title><link>https://johnjwang.com/post/2026/09/15/why-are-there-suddenly-so-many-gambling-companies/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/09/15/why-are-there-suddenly-so-many-gambling-companies/</guid><description>&lt;p>&lt;img src="https://johnjwang.com/images/us-sports-betting-growth.svg" alt="Annual US sports betting handle reported by the American Gaming Association grew from 6.58 billion dollars in 2018 to 166.94 billion dollars in 2025. Commercial and state-regulated sportsbooks only; prediction markets are excluded.">&lt;/p>
&lt;p>&lt;em>Source: American Gaming Association annual reports and revenue tracker; &lt;a href="#chart-sources">data and methodology&lt;/a>. Handle is the total amount wagered, including money that gets bet again after a win. It is not operator revenue or bettors&amp;rsquo; net losses. The AGA sportsbook series does not include Kalshi or Polymarket.&lt;/em>&lt;/p>
&lt;p>It feels like gambling companies are suddenly everywhere. DraftKings and FanDuel are part of watching sports. Kalshi and Polymarket let you put money behind opinions about elections, economic releases, and games. What used to feel like a fairly separate activity now shows up in the same places where you follow the news or check your investments.&lt;/p>
&lt;p>The graph gives some sense of how much has changed. Annual wagers through the sportsbooks tracked by the AGA grew roughly &lt;strong>25 times&lt;/strong> between 2018 and 2025. And that&amp;rsquo;s before adding prediction markets, which operate through a different structure and aren&amp;rsquo;t included in those numbers.&lt;/p>
&lt;p>My read is that we&amp;rsquo;re watching two overlapping expansions. First, states opened up sports betting. Then prediction markets started testing how much of the same activity could happen through financial exchanges. In both cases, software made it much easier to turn permission to operate into a product that millions of people could use.&lt;/p>
&lt;h2 id="first-the-law-changed">First, the law changed&lt;/h2>
&lt;p>The biggest reason for the timing is surprisingly straightforward. In May 2018, the Supreme Court struck down the Professional and Amateur Sports Protection Act in &lt;a href="https://www.supremecourt.gov/opinions/17pdf/16-476_dbfi.pdf">Murphy v. NCAA&lt;/a>. That federal law had largely prevented states from authorizing sports betting. The decision let states make their own choices; it didn&amp;rsquo;t itself legalize sports betting everywhere.&lt;/p>
&lt;p>That created a succession of new markets. Each state that allowed online wagering gave companies another group of customers to compete for. The AGA credits new markets and mobile launches in places including New York, Louisiana, and Maryland with helping drive &lt;a href="https://www.americangaming.org/resources/state-of-the-states-2023/">2022&amp;rsquo;s expansion&lt;/a>. Five more states launched legal sports betting in &lt;a href="https://www.americangaming.org/resources/state-of-the-states-2024/">2023&lt;/a>.&lt;/p>
&lt;p>This is important when reading the graph. Some growth is people betting more. Some is people betting legally instead of through an offshore site or a bookie. Some is the measured market expanding as more states participate. The chart alone can&amp;rsquo;t tell us how much comes from each.&lt;/p>
&lt;p>For a company, though, all three can create an opportunity. You don&amp;rsquo;t need to invent people&amp;rsquo;s interest in betting on football. You need to become the app they open once it&amp;rsquo;s available where they live.&lt;/p>
&lt;h2 id="phones-changed-the-size-of-the-opportunity">Phones changed the size of the opportunity&lt;/h2>
&lt;p>Imagine two versions of the same business. In one, a customer travels to a casino to place a bet. In the other, they open an app during a commercial break.&lt;/p>
&lt;p>The second version can become a much more frequent habit. It also gives the company more opportunities to offer another bet: before a game, during it, or on an individual player&amp;rsquo;s performance. The scarce resource becomes the customer&amp;rsquo;s attention.&lt;/p>
&lt;p>That helps explain why the advertising is so visible. DraftKings reported roughly &lt;a href="https://ir.aboutdraftkings.com/news/news-details/2025/DraftKings-Reports-Fourth-Quarter-and-Fiscal-Year-2024-Results-02-13-2025/default.aspx">1.26 billion dollars in sales and marketing expense in 2024&lt;/a>, across its business. That&amp;rsquo;s a substantial amount of money spent making sure people recognize and return to an app.&lt;/p>
&lt;p>Sports organizations became distribution partners, too. The NBA named DraftKings and FanDuel &lt;a href="https://pr.nba.com/draftkings-and-fanduel-become-co-official-sports-betting-partners-of-the-nba/">co-official sports betting partners in 2021&lt;/a>, with rights to league and team branding and integrations across NBA platforms. Betting could now appear inside the experience of being a fan.&lt;/p>
&lt;p>The business logic is easy to understand. If a customer keeps coming back, acquiring that customer can be worth a lot. But the enormous wagering total isn&amp;rsquo;t the amount companies get to keep. In 2025, the AGA reported &lt;strong>166.94 billion dollars in handle and 16.96 billion dollars in sportsbook revenue&lt;/strong>—about 10% of the amount wagered, before operating expenses and taxes. It also reported &lt;a href="https://www.americangaming.org/commercial-gaming-revenue-hits-78-7-billion-in-2025-driving-record-18-1-billion-in-gaming-taxes-nationwide/">3.71 billion dollars in state sportsbook taxes&lt;/a>. Customers, operators, sports partners, and state governments all became participants in a much larger business.&lt;/p>
&lt;h2 id="prediction-markets-opened-another-route">Prediction markets opened another route&lt;/h2>
&lt;p>Kalshi and Polymarket look similar to sportsbooks from a user&amp;rsquo;s perspective: put money behind an outcome, and get paid if you&amp;rsquo;re right. But the structure matters.&lt;/p>
&lt;p>A conventional sportsbook posts odds and takes bets. An exchange matches buyers and sellers of contracts. A simple event contract might pay one dollar if a specified event happens and zero if it doesn&amp;rsquo;t. Buy it for 60 cents and hold it to settlement, and you either make 40 cents or lose 60 cents, before fees. The price can be read as a rough market-implied probability, although fees, liquidity, and who is trading can distort it.&lt;/p>
&lt;p>Kalshi received &lt;a href="https://www.cftc.gov/PressRoom/PressReleases/8302-20">CFTC designation as a contract market in 2020&lt;/a>. The CFTC is the federal regulator for derivatives markets. Polymarket took a different path: in July 2025 it announced the &lt;a href="https://www.prnewswire.com/news-releases/polymarket-acquires-cftc-licensed-exchange-and-clearinghouse-qcex-for-112-million-302509626.html">112-million-dollar acquisition of QCEX&lt;/a>, a US-regulated exchange and clearinghouse, to support its return to the US. Its international platform and US business shouldn&amp;rsquo;t be treated as interchangeable when discussing regulation or trading volumes.&lt;/p>
&lt;p>The commercial attraction is obvious. If event contracts can operate under federal derivatives rules, companies have a potential route to customers beyond the state-by-state sportsbook system. That possibility is a powerful incentive to enter the market.&lt;/p>
&lt;p>But the boundary remains contested. In April 2026, the &lt;a href="https://www.cftc.gov/PressRoom/PressReleases/9206-26">CFTC sued Arizona, Connecticut, and Illinois&lt;/a>, asserting its exclusive jurisdiction over prediction markets. States have argued that sports contracts are gambling subject to their laws. Courts have not produced a uniform answer: in August, an appeals panel &lt;a href="https://apnews.com/article/2168b6c0837ad9b4f0f63b04633d8835">declined to let Kalshi resume sports and election trading in Nevada&lt;/a> while litigation continued.&lt;/p>
&lt;p>So this isn&amp;rsquo;t simply a story about an unregulated industry. It&amp;rsquo;s a fight over which regulatory framework applies, and what products that framework permits. That fight is still underway as of September 2026.&lt;/p>
&lt;h2 id="more-brands-can-mean-more-ways-into-the-same-market">More brands can mean more ways into the same market&lt;/h2>
&lt;p>There&amp;rsquo;s another reason it feels like the number of betting companies has exploded: an existing financial app can add prediction markets without building an exchange itself.&lt;/p>
&lt;p>Robinhood &lt;a href="https://robinhood.com/us/en/newsroom/robinhood-prediction-markets-hub/">launched its prediction markets hub in March 2025&lt;/a>, initially offering contracts through Kalshi. The launch included both economic and basketball outcomes. In May 2026, Interactive Brokers announced &lt;a href="https://www.interactivebrokers.com/en/general/about/mediaRelations/5-14-26.php">one interface connecting Kalshi, CME Group, and ForecastEx&lt;/a>.&lt;/p>
&lt;p>That means counting apps can overstate the number of independent markets underneath them. Several familiar brands can distribute access to the same exchange. For the exchange, distribution brings traders. For the distributor, it adds something else an existing customer can do with an existing account.&lt;/p>
&lt;p>Prediction markets also have a useful distribution mechanism of their own: the price is content. A probability about an election can be shared in an article or group chat. Someone who would never browse a sportsbook can encounter a market while reading the news.&lt;/p>
&lt;h2 id="forecasting-and-gambling-can-coexist">Forecasting and gambling can coexist&lt;/h2>
&lt;p>I think the appeal of prediction markets is real. People have opinions about uncertain events, and putting money behind a claim can make it more informative than a confident social media post. A well-designed market can aggregate information or let someone offset a risk they already face.&lt;/p>
&lt;p>But those uses don&amp;rsquo;t tell us what drives the commercial business. Sports provide frequent events, clear results, and an existing audience. The AGA &lt;a href="https://americangaming.org/aga-estimates-29-5-billion-in-legal-nfl-wagering-flat-year-over-year-growth-as-backdoor-sports-betting-on-prediction-markets-explodes/">estimated in September 2026 that sports represented about 80% of Kalshi&amp;rsquo;s volume&lt;/a>. That&amp;rsquo;s an industry association&amp;rsquo;s estimate, from an organization representing competitors and advocating against these products. Still, it illustrates why the two industries are colliding.&lt;/p>
&lt;p>The same interface can serve someone hedging an economic risk and someone looking for another wager. Calling it a prediction market doesn&amp;rsquo;t resolve the question of which behavior its business model rewards.&lt;/p>
&lt;p>That, to me, is why there are suddenly so many gambling companies. A large existing appetite met newly available legal routes, inexpensive digital distribution, and businesses with a strong incentive to turn occasional participation into a recurring habit. Prediction markets then expanded both the range of things people could bet on and the set of companies that could distribute those bets.&lt;/p>
&lt;p>The interesting question now is how much of the next wave will produce useful information—and how much will make placing another bet an ordinary part of opening any app.&lt;/p>
&lt;h2 id="chart-sources">Chart sources&lt;/h2>
&lt;p>The opening chart shows annual &lt;strong>nominal US dollars wagered through commercial and state-regulated sportsbooks covered by the AGA&lt;/strong>. It is not a count of companies, an estimate of all US gambling, or a prediction-market volume series. It does not comprehensively cover tribal sportsbook activity. Calendar year 2026 is omitted because it is incomplete.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Year&lt;/th>
&lt;th style="text-align:right">Handle, billions of dollars&lt;/th>
&lt;th>AGA source&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>2018&lt;/td>
&lt;td style="text-align:right">6.58&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/wp-content/uploads/2021/05/AGA-2021-State-of-the-States_FINALweb-150ppi.pdf">State of the States 2021&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2019&lt;/td>
&lt;td style="text-align:right">13.07&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/wp-content/uploads/2021/05/AGA-2021-State-of-the-States_FINALweb-150ppi.pdf">State of the States 2021&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2020&lt;/td>
&lt;td style="text-align:right">21.60&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/wp-content/uploads/2022/05/AGA-State-of-the-States-2022.pdf#page=11">State of the States 2022, p. 11&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2021&lt;/td>
&lt;td style="text-align:right">57.71&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/wp-content/uploads/2022/05/AGA-State-of-the-States-2022.pdf#page=11">State of the States 2022, p. 11&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2022&lt;/td>
&lt;td style="text-align:right">93.20&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/resources/state-of-the-states-2023/">State of the States 2023&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2023&lt;/td>
&lt;td style="text-align:right">121.06&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/resources/state-of-the-states-2024/">State of the States 2024&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2024&lt;/td>
&lt;td style="text-align:right">149.90&lt;/td>
&lt;td>&lt;a href="https://americangaming.org/resources/state-of-the-states-2025/">State of the States 2025&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2025&lt;/td>
&lt;td style="text-align:right">166.94&lt;/td>
&lt;td>&lt;a href="https://www.americangaming.org/commercial-gaming-revenue-hits-78-7-billion-in-2025-driving-record-18-1-billion-in-gaming-taxes-nationwide/">2025 Commercial Gaming Revenue release&lt;/a>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>These are the figures in the cited publications; the AGA revises historical data as state reports change, so they can differ from earlier releases or later comparisons. The cited AGA reports do not provide a comparable annual US-only Kalshi-and-Polymarket series. Adding global exchange volume to US sportsbook handle would imply a precision and comparability the data don&amp;rsquo;t support.&lt;/p></description></item><item><title>Learnings from the Codex repo</title><link>https://johnjwang.com/post/2026/08/27/learnings-from-the-codex-repo/</link><pubDate>Thu, 27 Aug 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/08/27/learnings-from-the-codex-repo/</guid><description>&lt;p>I&amp;rsquo;ve been fascinated recently at what the best practices in the new age of engineering look like. But it&amp;rsquo;s hard to find real data on best practices. For example, X has a ton of &amp;ldquo;information&amp;rdquo; about what&amp;rsquo;s happening at the cutting edge, but it&amp;rsquo;s very hard to validate whether any of it is real. Talks suffer from the same problem as an exec at a company can say anything they want or stretch the truth. Are people really not looking at any of their code? Are people productively using billions of tokens every day? It&amp;rsquo;s hard to get ground truth on that.&lt;/p>
&lt;p>Because of that, I thought OpenAI&amp;rsquo;s open source &lt;a href="https://github.com/openai/codex">Codex repo&lt;/a> would be an good place to get a bit closer to ground truth:&lt;/p>
&lt;ul>
&lt;li>OpenAI&amp;rsquo;s internal teams have access to edge of the frontier (it&amp;rsquo;s rumored that Astra is a step change above GPT-5.6-sol for example)&lt;/li>
&lt;li>The Codex repo has been open source since it was launched in 2025, so there&amp;rsquo;s plenty of stuff that has happened in the open.&lt;/li>
&lt;li>OpenAI likely has the best pulse of any company in the world (save a few) on how to build software in the agentic engineering way&lt;/li>
&lt;/ul>
&lt;p>So I kicked off an analysis of the repo using a combination of Codex (gpt-5.6-sol) and Claude Code (Fable 5) to try to see what they were doing.&lt;/p>
&lt;p>My immediate observation is that Codex has seen a step change increase in PRs per week over the last few months. In May 2025, the Rust implementation had 98 commits from six authors, and one person wrote 89 of them. In the first 25 days of August 2026, it had more than 1,000 commits from 135 authors. This is a big jump, and it&amp;rsquo;s an interesting convergence of a few factors: a) likely a lot of coding agent usage b) aggressive hiring for the team and c) heavy investments in guardrails and automation rules that make it easier for many people and agents to work at the same time.&lt;/p>
&lt;h1 id="graduating-from-small-team--handwritten-ish-code-to-large-team-with-agents">Graduating from small team / handwritten-ish code to large team with agents&lt;/h1>
&lt;p>The &lt;a href="https://github.com/openai/codex">public Codex repository&lt;/a> started on April 16, 2025 as a TypeScript CLI. Since then, the repo has changed quite significantly. The initial era of the Codex repo had a small number of authors pushing out everything. For example, Michael Bolin &lt;a href="https://github.com/openai/codex/commit/31d0d7a3059063ef266cab1644aa82f87a866c19">wrote the original Rust implementation&lt;/a> and also 150 of the first 169 Rust commits.&lt;/p>
&lt;p>However, over time, this has changed dramatically:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th style="text-align:right">May 2025&lt;/th>
&lt;th style="text-align:right">March 2026&lt;/th>
&lt;th style="text-align:right">August 2026&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Commits per month&lt;/td>
&lt;td style="text-align:right">98&lt;/td>
&lt;td style="text-align:right">791&lt;/td>
&lt;td style="text-align:right">893&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Regular author identities with 5+ commits&lt;/td>
&lt;td style="text-align:right">2&lt;/td>
&lt;td style="text-align:right">28&lt;/td>
&lt;td style="text-align:right">35&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Share written by the busiest author&lt;/td>
&lt;td style="text-align:right">91%&lt;/td>
&lt;td style="text-align:right">14%&lt;/td>
&lt;td style="text-align:right">18%&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Authors landing changes on the median active day&lt;/td>
&lt;td style="text-align:right">1&lt;/td>
&lt;td style="text-align:right">12&lt;/td>
&lt;td style="text-align:right">~18&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Rust crates touched on the median active day&lt;/td>
&lt;td style="text-align:right">4&lt;/td>
&lt;td style="text-align:right">16&lt;/td>
&lt;td style="text-align:right">~28&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The volume of changes grew roughly 8x, from 98 commits in May 2025 to 791 in March 2026. By August, the repository was already hitting 900 commits. Commit counts are an imperfect measure of output, especially as development practices change, but the surrounding evidence points to a similar story &amp;ndash; there were more authors were shipping on the same day, across many more parts of the codebase.&lt;/p>
&lt;p>Even though coding agents have recently gotten much better, part of the sizeable increase in Codex velocity comes down to sheer team size. OpenAI appears to have put a lot more people on the project (137 members now) and generally been able to keep people working on separate parallel streams of work (most authors seem to be working on separate, parallel crates).&lt;/p>
&lt;p>With that many more people and agents changing the code at the same time, the rules around how they work become much more important.&lt;/p>
&lt;h1 id="agent-guardrails-and-rules">Agent guardrails and rules&lt;/h1>
&lt;p>The first interesting thing is the repo&amp;rsquo;s &lt;a href="https://github.com/openai/codex/blob/4fea5234664ebc628b1a5322761cb132eaacc9e2/AGENTS.md">&lt;code>AGENTS.md&lt;/code>&lt;/a> file. The Codex repo takes this fairly seriously: it&amp;rsquo;s clear they&amp;rsquo;ve put a lot of thought into and have been aggressive at removing slop and extras (the main file is 322 lines).&lt;/p>
&lt;p>There are a few rules in particular that I found interesting:&lt;/p>
&lt;p>&lt;strong>1. &amp;ldquo;Never add or modify any code related to &lt;code>CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR&lt;/code> or &lt;code>CODEX_SANDBOX_ENV_VAR&lt;/code>.&amp;rdquo;&lt;/strong> &lt;a href="https://github.com/openai/codex/blob/4fea5234664ebc628b1a5322761cb132eaacc9e2/codex-rs/core/tests/suite/compact_resume_fork.rs#L18-L60">Some tests check these variables&lt;/a> to figure out whether they can safely run nested sandboxing or network behavior. An agent might otherwise see those checks, decide they are getting in the way of a test, and &amp;ldquo;fix&amp;rdquo; them. I think it&amp;rsquo;s quite smart to find these types of cheating behaviors that you&amp;rsquo;ve seen in test runs and encode them as rules.&lt;/p>
&lt;p>&lt;strong>2. &amp;ldquo;Do not add tests for values that are statically defined&amp;rdquo; and &amp;ldquo;Do not add negative tests for logic that was removed.&amp;rdquo;&lt;/strong> These rules are aimed at tests that make a change look more rigorous without checking any meaningful behavior. Coding agents are very good at generating this kind of plausible-looking test volume, so explicitly telling them what not to test keeps the suite focused on behavior that can actually regress.&lt;/p>
&lt;p>&lt;strong>3. &amp;ldquo;Features that change the agent logic MUST add an integration test.&amp;rdquo;&lt;/strong> Agent behavior usually comes from the combination of context, tools, model responses, and the turn loop, so a small unit test often can&amp;rsquo;t tell you whether the agent will actually do the right thing. Codex&amp;rsquo;s &lt;a href="https://github.com/openai/codex/blob/4fea5234664ebc628b1a5322761cb132eaacc9e2/codex-rs/core/tests/common/test_codex.rs#L325-L341">&lt;code>TestCodexBuilder&lt;/code> test harness&lt;/a> runs the real agent loop against fake model streams. New tests are also supposed to use &lt;a href="https://github.com/openai/codex/blob/4fea5234664ebc628b1a5322761cb132eaacc9e2/codex-rs/core/tests/common/test_codex.rs#L485-L499">an automatic environment setup&lt;/a> so they keep working when the app-server and exec-server are on different operating systems.&lt;/p>
&lt;p>&lt;strong>4. &amp;ldquo;Avoid bool or ambiguous &lt;code>Option&lt;/code> parameters.&amp;rdquo;&lt;/strong> If an API can&amp;rsquo;t be changed, opaque values like &lt;code>false&lt;/code>, &lt;code>None&lt;/code>, or a bare number need an exact &lt;code>/*param_name*/&lt;/code> comment next to them. This is already more specific than what you normally see in an instruction file, but the interesting part is that they didn&amp;rsquo;t leave it as an instruction.&lt;/p>
&lt;h1 id="lint-rules">Lint rules&lt;/h1>
&lt;p>The ambiguous argument rule is probably my favorite example of what the team does next. Rust makes it easy to end up with calls like this:&lt;/p>
&lt;pre>&lt;code class="language-rust">foo(false, None, 1000)
&lt;/code>&lt;/pre>
&lt;p>It is basically impossible to review that without jumping to the function definition. The Codex team would prefer that you change the API, but when that is impractical they require comments next to ambiguous literal arguments:&lt;/p>
&lt;pre>&lt;code class="language-rust">foo(
/*enabled*/ false,
/*parent_turn_id*/ None,
/*timeout_ms*/ 1000,
)
&lt;/code>&lt;/pre>
&lt;p>They then built a &lt;a href="https://github.com/openai/codex/commit/4b31848f5bd112816eb0f7f4e9a33dc2330ea617">custom lint&lt;/a> that checks whether the comment exactly matches the parameter name in the function definition. It was introduced in March 2026, applied across the Rust workspace a couple of days later, and then moved into Bazel CI.&lt;/p>
&lt;p>The other thing worth saying is that these rules did not appear all at once. Support for &lt;code>AGENTS.md&lt;/code> landed in May 2025. More detailed test guidance followed that summer. Snapshot requirements came in February 2026, the warning about &lt;code>codex-core&lt;/code> in March, the trait guidance in April, and the model context and change-size rules in June. It looks a lot like the team is taking repeated review feedback and putting it somewhere that the next person or agent will see before making the same mistake.&lt;/p>
&lt;p>You can see a rough pattern here: a problem first shows up repeatedly in code review, it gets written into &lt;code>AGENTS.md&lt;/code> so humans and agents see it before making a change, and then the team turns it into a lint or CI check once the rule is stable enough. Not every rule makes it to the last step, but the expensive and objectively checkable ones tend to.&lt;/p>
&lt;p>Codex has 38 lint rules, and I think it&amp;rsquo;s part of what makes the repo easier to work on as an agent because it has a large number of automated checks that prevent out-of policy behavior (and in a deterministic way).&lt;/p>
&lt;h1 id="investing-in-an-integration-test-harness">Investing in an integration test harness&lt;/h1>
&lt;p>One other thing that I thought was interesting was how much the Codex team has invested in their tests. Tests compose about 615k lines (or 40%) of the codebase, and Codex has also invested in a full mock test harness: they&amp;rsquo;ve spent around 7k lines of code across 300+ commits to built out a harness that can stub out http responses from the Responses API. This integration test harness will run a real Codex thread, and it can call tools, apply approvals, and generally iterate on requests as if it&amp;rsquo;s getting responses back from the LLM. It&amp;rsquo;s a really interesting and deterministic way to test a large amount of behavior, and I think it&amp;rsquo;s quite smart to have invested so heavily in this because the Codex loop is ultimately the most important part of the product.&lt;/p>
&lt;p>Another area that I was curious about (especially because our team has seen our test suites slow down as our coding agents get better and faster at writing tests), is how they&amp;rsquo;re still able to keep up speed of development despite a large number of tests. Codex doesn&amp;rsquo;t run the same enormous test suite at every stage. While someone is working on a change, the setup is to test only the affected Rust crate. If you change the terminal UI, for example, you run the terminal UI tests, not the entire workspace. This keeps the everyday edit-test loop reasonably fast.&lt;/p>
&lt;p>Before a change is merged, CI broadens the coverage. Bazel runs the compatible Rust tests across macOS, Linux, and Windows, while separate jobs check the SDKs, formatting, dependencies, and repository rules. The largest workloads are divided across machines and reuse remote build caches.&lt;/p>
&lt;p>After the code reaches main, Codex pays for a much more exhaustive pass. It runs the full Cargo test suite across five platform and architecture combinations. Each platform compiles the tests once, packages the resulting binaries, and distributes their execution across four machines. Slower native Windows checks, release builds, and remote-environment tests also happen here.&lt;/p>
&lt;p>Basically, Codex has set up their environment so only relevant tests are run while developing, and get progressively more thorough as a piece of code gets closer to deployment. This makes it so you can still have fast deploys and ship quickly, while keeping safety and correctness in the long run.&lt;/p>
&lt;h1 id="migrations-with-linting-and-feature-flags">Migrations with linting and feature flags&lt;/h1>
&lt;p>The other fascinating thing we observed in Codex&amp;rsquo;s codebase is some good old-fashioned, high-quality engineering. Their engineering team uses a combination of feature flags, linters, and other rollout mechanisms to ensure safety but also speeding rollout. Large changes are staged so the old and new implementations can coexist, and the migration plan is eventually encoded in lint rules instead of depending on everyone remembering it.&lt;/p>
&lt;p>The TUI migration is a nice example. On March 16, the team created a &lt;a href="https://github.com/openai/codex/commit/db89b73a9cd553ac2a2afda93c9f9bdcc223540c">temporary parallel implementation&lt;/a> behind a &lt;code>tui_app_server&lt;/code> feature flag. Ten days later, they &lt;a href="https://github.com/openai/codex/commit/e7139e14a29de0411a61658a0e5765e2502a0cd2">enabled it by default&lt;/a>. Once it was stable, they &lt;a href="https://github.com/openai/codex/commit/d65deec61718f291cba5a51de9489603865779df">deleted the old TUI and retired the feature flag&lt;/a>, while continuing to accept the old flag in configuration so existing users would not get an error.&lt;/p>
&lt;p>Two weeks later, they added a &lt;a href="https://github.com/openai/codex/commit/66e13efd9cfd0dd3525713c8cf27ea7fbcb6b3e4">CI rule preventing the TUI from importing &lt;code>codex-core&lt;/code> directly&lt;/a>. I think this is a particularly good way to finish a migration. It&amp;rsquo;s easy to clean up a dependency once, but on a team this large, someone will eventually add it back unless CI stops them. The feature flag made it easier to move over incrementally, and the lint rule made sure the team couldn&amp;rsquo;t accidentally undo the work later.&lt;/p>
&lt;h1 id="conclusion-speed--testing-boundaries-lint-hiring">Conclusion: speed == testing, boundaries, lint, hiring&lt;/h1>
&lt;p>The Codex team is running and building upon a highly used, production-level codebase while moving incredibly quickly. They&amp;rsquo;ve ramped up velocity considerably in the last few months through a combination of AI coding agent usage as well as hiring for new team members. There are a lot more people working on Codex than there were a year ago and many of those people appear to be very effective engineers. Also, the codebase is explicitly organized to give agents context. OpenAI have invested in the tests and boundaries that let all of those people and agents work at the same time.&lt;/p>
&lt;p>The interesting thing is that at least for the Codex team, as implementation got cheaper, it did not make the rest of engineering less important. Codex put a lot of work into a well-designed system, particularly focused on the classic parts of engineering excellence: testing, high quality boundaries and abstractions, automatic linting systems, and of course hiring good people. All of those things seemed to have gotten more important.&lt;/p></description></item><item><title>How Claude's watermarking (probably) works</title><link>https://johnjwang.com/post/2026/08/12/how-claude-watermarking-probably-works/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/08/12/how-claude-watermarking-probably-works/</guid><description>&lt;p>&lt;strong>Update (2026-08-20):&lt;/strong> Anthropic has &lt;a href="https://www.anthropic.com/news/claude-text-watermark">since published technical details&lt;/a> confirming that Claude&amp;rsquo;s watermark is based on SynthID-Text — a keyed statistical watermark on token selection, exactly as this post hypothesized. See the &lt;a href="#update-2026-08-20-anthropic-confirms-its-synthid-text">update section&lt;/a> near the end of the post for a full rundown.&lt;/p>
&lt;hr>
&lt;p>Yesterday, &lt;a href="https://support.claude.com/en/articles/16266773-how-claude-marks-ai-generated-content">Anthropic announced&lt;/a> that they had started watermarking AI-generated content. Folks across the internet were particularly up in arms about it (I think rightfully so), especially because this apparently is happening to all Claude models whether or not you are in the EU. I wanted to investigate what they&amp;rsquo;re actually doing and whether it&amp;rsquo;s perceptible or changeable.&lt;/p>
&lt;p>Anthropic provides some insight into their approach in their article &lt;a href="https://support.claude.com/en/articles/16266773-how-claude-marks-ai-generated-content">How Claude marks AI-generated content&lt;/a>. Though it doesn&amp;rsquo;t actually provide any technical details on the implementation, it provides some guidance to help draw a wide net around the scheme they&amp;rsquo;re using. The key clues Anthropic left in their help center article:&lt;/p>
&lt;ul>
&lt;li>The scheme &amp;ldquo;weaves an imperceptible watermark directly into the text itself. You won’t see it, and it doesn’t change the meaning, quality, or readability of Claude’s response.&amp;rdquo;&lt;/li>
&lt;li>The watermarking doesn&amp;rsquo;t work well on very short text.&lt;/li>
&lt;li>The watermark seems to have started recently (August 2nd or later)&lt;/li>
&lt;/ul>
&lt;p>This helps us narrow down the possibilities quite a bit.&lt;/p>
&lt;h1 id="setup">Setup&lt;/h1>
&lt;p>To actually get to the bottom of what Anthropic are doing, I realized that there are some interesting experiments you can run. &lt;a href="https://www.sri.inf.ethz.ch/blog/probingsynthid">Gloaguen et al.&lt;/a> created specific tests to check for statistical watermarking, and we can also perform an analysis of Claude outputs to check for things like hidden unicode or whitespace results.&lt;/p>
&lt;p>For good measure, I also downloaded a dump of my Claude chats (I&amp;rsquo;ve used Claude Code since 2/4/2025 and have recorded 1206 sessions) and did a quick comparison to see if there was any changepoint around early August that percepitbly changed the mix of tokens that Fable 5 output (my usual daily driver model). I wasn&amp;rsquo;t able to find any perceptible difference in this historical analysis, which confirms Anthropic&amp;rsquo;s claim that the watermarking is generally imperceptible unless using more specific tests.&lt;/p>
&lt;h1 id="no-hidden-unicode-or-whitespace">No hidden unicode or whitespace&lt;/h1>
&lt;p>The second thing I checked is whether there&amp;rsquo;s hidden unicode or whitespace or punctuation patterns. This was pretty conclusive: they&amp;rsquo;re not doing something so simple.&lt;/p>
&lt;p>An analysis across 7.2 million extracted prose characters (both on historical Claude Code text as well as generated Claude Code text on August 11) showed that the only unicode characters that were output by Claude were reasonable and part of day to day usage:&lt;/p>
&lt;ul>
&lt;li>Curly quotation marks, apostrophes, and horizontal ellipses&lt;/li>
&lt;li>Em/en dashes (A LOT of them unfortunately)&lt;/li>
&lt;li>Mathematical symbols&lt;/li>
&lt;li>Accented or non-English characters&lt;/li>
&lt;li>Emoji&lt;/li>
&lt;/ul>
&lt;p>An audit by Codex, with me spot checking about 10 samples, found no anomalous instances that were consistent with a hidden Unicode watermark. I similarly found no whitespace encoding marks.&lt;/p>
&lt;p>This evidence, combined with the fact that the watermarking is imperceptible and doesn&amp;rsquo;t work on short text, means that Anthropic is most likely using some form of statistical token watermarking.&lt;/p>
&lt;h1 id="statistical-watermarking-schemes">Statistical watermarking schemes&lt;/h1>
&lt;p>There are a few different schemes that are available that can add watermarking to text. I&amp;rsquo;ll talk about the simplest version, the green/red list created in 2023 by &lt;a href="https://arxiv.org/pdf/2301.10226">Kirchenbauer et al.&lt;/a>, because it&amp;rsquo;s the easiest to explain and once you understand it will allow you to understand how these schemes generally work.&lt;/p>
&lt;h2 id="greenred-lists">Green/red lists&lt;/h2>
&lt;p>This scheme is super basic, but it&amp;rsquo;s quite clever and fun. Here are the steps:&lt;/p>
&lt;ol>
&lt;li>Split your output vocabulary into two sets: a green and a red list. Make sure they&amp;rsquo;re chosen uniformly at random.&lt;/li>
&lt;li>Then for the green list, add $\delta$ to all of the logits and sample from the updated distribution at decoding time.&lt;/li>
&lt;/ol>
&lt;p>To figure out whether a text has been watermarked, then you compute the z-score that the tokens in the green set appear. If the text wasn&amp;rsquo;t watermarked, then the expected value of text in the green list is $T/2$, where $T$ is the token count, with a standard deviation of $\frac{\sqrt{T}}{2}$. So the suspiciousness of getting this outcome is just the z-score:&lt;/p>
$$
z = \frac{2G-T}{\sqrt{T}}.
$$
&lt;p>If some red token already has probability 0.99 (which would be a huge logit lead) a big $\delta$ nudge to the greens still wouldn&amp;rsquo;t overtake it. So the bias only changes words that have a lot of options and generally high entropy.&lt;/p>
&lt;p>For an example, let&amp;rsquo;s say you asked your LLM to write a poem, you might have the following potential sentences that get generated:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Word&lt;/th>
&lt;th>List&lt;/th>
&lt;th>Sentence&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>crisp&lt;/td>
&lt;td>Green&lt;/td>
&lt;td>It was a crisp morning&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>quiet&lt;/td>
&lt;td>Green&lt;/td>
&lt;td>It was a quiet morning&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>foggy&lt;/td>
&lt;td>Red&lt;/td>
&lt;td>It was a foggy morning&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>cold&lt;/td>
&lt;td>Red&lt;/td>
&lt;td>It was a cold morning&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>If it was watermarked, you&amp;rsquo;d get an imperceptibly higher percentage of generating &amp;ldquo;crisp&amp;rdquo; or &amp;ldquo;quiet&amp;rdquo; morning (depending on how strongly the LLM provider decided to watermark with their $\delta$ value). Do this across all the words that an LLM is generating, and you can get high levels of confidence in your watermarking.&lt;/p>
&lt;p>That being said, I don&amp;rsquo;t believe Green/red lists are used in practice because they&amp;rsquo;re easy to detect and there are schemes that use the model&amp;rsquo;s available entropy more efficiently (and thus harder to detect and less likely to change the outputs of the model). The most well known scheme is &lt;a href="https://www.nature.com/articles/s41586-024-08025-4">SynthID-Text&lt;/a> which was developed by Google Deepmind and is used by Google in production.&lt;/p>
&lt;h2 id="synthid-text">SynthID-Text&lt;/h2>
&lt;p>SynthID-Text is the same idea as green/red lists, but using a slightly different approach that Deepmind calls tournament sampling. Here are the steps:&lt;/p>
&lt;ol>
&lt;li>At each decoding step, hash a secret key together with the last $h$ tokens of context to produce a seed. That seed assigns every vocabulary token one $g$ value in $[0,1]$ per tournament layer.&lt;/li>
&lt;li>Draw your candidate output tokens using the model&amp;rsquo;s logits as normal.&lt;/li>
&lt;li>Run a tournament bracket where candidates face off in pairs, and the candidate with the higher $g$ value for that layer advances.&lt;/li>
&lt;li>Output the tournament winner as the decoded token.&lt;/li>
&lt;/ol>
&lt;p>To detect the watermark, you just need the secret key. You can compute the seed value and the $g$ values associated with every token in the text:&lt;/p>
$$
\operatorname{Score}(x)=\frac{1}{mT}\sum_{t=1}^{T}\sum_{\ell=1}^{m}g_\ell(x_t,r_t),
$$
&lt;p>Then compare the result with the null distribution and generate a standardized score similar to the Green/red list detection.&lt;/p>
&lt;p>SynthID also uses repeated-context masking: if the same $h$-token context window has already been used during a response, the implementation can decline to watermark that position. This prevents a repeated context from receiving the same bias over and over, but it matters substantially for testing because using the wrong context length can accidentally trigger the mask and hide the signal.&lt;/p>
&lt;p>SynthID is a bit more disguised than Green/red lists because every candidate is drawn from the model&amp;rsquo;s own distribution, so the tournament can only promote words the model already considered saying. When the model is pretty certain about the next token, there&amp;rsquo;s low entropy and not much watermarking (just like Green/red lists). The signal gets stronger for high entropy words, which is also why these schemes need a decent amount of text before detection becomes reliable.&lt;/p>
&lt;p>When the model is nearly certain about the next token, there is little entropy available for any sampling-based watermark to use. The signal accumulates mainly at higher-entropy positions, which is one reason these schemes need a decent amount of text before detection becomes reliable.&lt;/p>
&lt;p>Going back to our poem, say the model draws four candidates and we run a two-layer tournament using the continuous-score variant:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Matchup&lt;/th>
&lt;th>g-values&lt;/th>
&lt;th>Winner&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>crisp vs. foggy (layer 1)&lt;/td>
&lt;td>0.71 vs. 0.24&lt;/td>
&lt;td>crisp&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>quiet vs. cold (layer 1)&lt;/td>
&lt;td>0.90 vs. 0.42&lt;/td>
&lt;td>quiet&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>crisp vs. quiet (layer 2)&lt;/td>
&lt;td>0.35 vs. 0.83&lt;/td>
&lt;td>quiet&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>So &amp;ldquo;quiet&amp;rdquo; gets emitted because of its tournament $g$ values. It&amp;rsquo;s clever because any single word looks like a standard part of the output, but with the secret key you can test whether emitted words repeatedly align with the keyed scores. It&amp;rsquo;s also quite nice because you can adjust the number of layers to change the tradeoff between detectability and model quality.&lt;/p>
&lt;p>SynthID is the only scheme that I know of (or ChatGPT/Claude knows of) which is running in production, and it seems like my best guess candidate given that it&amp;rsquo;s been publicized and run a scale by Google.&lt;/p>
&lt;h1 id="experimental-results">Experimental results&lt;/h1>
&lt;p>To see if Anthropic is running one of these kinds of statistical watermarks, I ran some of the black-box tests from the watermark detection literature with Codex GPT-5.6-sol[0].&lt;/p>
&lt;h2 id="greenred-list-detection">Green/red list detection&lt;/h2>
&lt;p>I had Codex run &lt;a href="https://www.sri.inf.ethz.ch/blog/probingsynthid">Gloaguen et al.&amp;rsquo;s&lt;/a> detection algorithm. In this, Claude is forced to complete sentences using one of four fruits:&lt;/p>
&lt;pre>&lt;code>I ate 111111111111111 peaches
I chose 222222222222222 plums
...
&lt;/code>&lt;/pre>
&lt;p>The prefix and repeated digit vary while the fruit alternatives remain fixed. If a classic keyed watermark partitions tokens into green and red sets, then a particular fruit should become unusually likely or unlikely.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Model/test&lt;/th>
&lt;th>Number of runs&lt;/th>
&lt;th>Permutation p-value&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Sonnet 5, compact digits&lt;/td>
&lt;td>1,800&lt;/td>
&lt;td>0.677&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Sonnet 5, spaced digits&lt;/td>
&lt;td>1,800&lt;/td>
&lt;td>0.556&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Fable 5&lt;/td>
&lt;td>1,200&lt;/td>
&lt;td>0.886&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The Sonnet tests used 10 prefixes, 9 digit contexts, and 20 calls for each combination, for 1,800 responses each. The Fable test used 6 digit contexts, for 1,200 responses. Each p-value was calculated from 100,000 permutations.&lt;/p>
&lt;p>All three were clear negative results. The Sonnet test was strong enough to rule out a fairly large, stable Green/red effect in this particular setup. It does not rule out a weaker watermark, a key that changes between requests, or a different kind of watermark entirely.&lt;/p>
&lt;h2 id="synthid-detection">SynthID detection&lt;/h2>
&lt;p>The next experiment looked for the fixed context window used by SynthID-like schemes. The basic setup forced Claude to return a line such as&lt;/p>
&lt;pre>&lt;code>I ate red green cherries
&lt;/code>&lt;/pre>
&lt;p>Here &lt;code>red&lt;/code> is a perturbation word and &lt;code>green&lt;/code> is repeated $H$ times after it. If the watermark only looks at the last $h$ tokens, &lt;code>red&lt;/code> should stop affecting the watermark once $H$ reaches $h$. For example, if $h=2$, I would expect a strong effect at $H=1$ and little or no effect at $H=2$. So the thing we&amp;rsquo;re looking for is a sharp drop at some value of $H$.&lt;/p>
&lt;p>Here&amp;rsquo;s an actual example of the experiment I ran:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:right">$H$&lt;/th>
&lt;th style="text-align:right">Repeat&lt;/th>
&lt;th>Actual response&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:right">1&lt;/td>
&lt;td style="text-align:right">0&lt;/td>
&lt;td>&lt;code>I ate red green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">1&lt;/td>
&lt;td style="text-align:right">1&lt;/td>
&lt;td>&lt;code>I ate red green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">1&lt;/td>
&lt;td style="text-align:right">2&lt;/td>
&lt;td>&lt;code>I ate red green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">2&lt;/td>
&lt;td style="text-align:right">0&lt;/td>
&lt;td>&lt;code>I ate red green green plums&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">2&lt;/td>
&lt;td style="text-align:right">1&lt;/td>
&lt;td>&lt;code>I ate red green green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">2&lt;/td>
&lt;td style="text-align:right">2&lt;/td>
&lt;td>&lt;code>I ate red green green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">3&lt;/td>
&lt;td style="text-align:right">0&lt;/td>
&lt;td>&lt;code>I ate red green green green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">3&lt;/td>
&lt;td style="text-align:right">1&lt;/td>
&lt;td>&lt;code>I ate red green green green cherries&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">3&lt;/td>
&lt;td style="text-align:right">2&lt;/td>
&lt;td>&lt;code>I ate red green green green plums&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>At larger scale, I calculated $Z(H)$, which measures how strongly changing the perturbation word changes Claude&amp;rsquo;s fruit choice. A value near zero would mean no detectable effect. $Z(1)=87.25$, which I saw in the experimental runs, means the test statistic was 87.25 (!!) standard deviations above what you would expect to see in randomized data:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:right">$H$&lt;/th>
&lt;th>Context form&lt;/th>
&lt;th style="text-align:right">Standardized perturbation effect $Z(H)$&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:right">1&lt;/td>
&lt;td>&lt;code>red green&lt;/code>&lt;/td>
&lt;td style="text-align:right">87.25&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">2&lt;/td>
&lt;td>&lt;code>red green green&lt;/code>&lt;/td>
&lt;td style="text-align:right">58.42&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">3&lt;/td>
&lt;td>&lt;code>red green green green&lt;/code>&lt;/td>
&lt;td style="text-align:right">33.64&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">4&lt;/td>
&lt;td>&lt;code>red&lt;/code> + 4×&lt;code>green&lt;/code>&lt;/td>
&lt;td style="text-align:right">37.22&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">5&lt;/td>
&lt;td>&lt;code>red&lt;/code> + 5×&lt;code>green&lt;/code>&lt;/td>
&lt;td style="text-align:right">38.46&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">6&lt;/td>
&lt;td>&lt;code>red&lt;/code> + 6×&lt;code>green&lt;/code>&lt;/td>
&lt;td style="text-align:right">25.34&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">7&lt;/td>
&lt;td>&lt;code>red&lt;/code> + 7×&lt;code>green&lt;/code>&lt;/td>
&lt;td style="text-align:right">19.28&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:right">8&lt;/td>
&lt;td>&lt;code>red&lt;/code> + 8×&lt;code>green&lt;/code>&lt;/td>
&lt;td style="text-align:right">25.10&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>That is an extremely strong result, with $H=1$ giving $p\approx0.00001$. Unfortunately, this test wasn&amp;rsquo;t conclusive because it only tells us that the perturbation word matters, and we didn&amp;rsquo;t actually see a sharp drop off on any $H$, only a slow decrease, which could mean that this isn&amp;rsquo;t a watermark at all, but rather just an effect that comes from the model.&lt;/p>
&lt;p>The full scan used 20,736 Sonnet 5 responses, with 2,592 at each value of $H$. The sharpest bend was at $H=2$, so I tested it again using fresh Sonnet 5 responses and also on Sonnet 4.6 (which based on my reading of Anthropic&amp;rsquo;s help center article is less likely to be watermarked because it&amp;rsquo;s an older model):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Endpoint&lt;/th>
&lt;th style="text-align:right">Observations&lt;/th>
&lt;th style="text-align:right">$Z(1)$&lt;/th>
&lt;th style="text-align:right">$Z(2)$&lt;/th>
&lt;th style="text-align:right">$Z(3)$&lt;/th>
&lt;th style="text-align:right">$D(2)$&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Sonnet 5, held-out confirmation&lt;/td>
&lt;td style="text-align:right">7,776&lt;/td>
&lt;td style="text-align:right">85.77&lt;/td>
&lt;td style="text-align:right">61.90&lt;/td>
&lt;td style="text-align:right">33.35&lt;/td>
&lt;td style="text-align:right">38.14&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Sonnet 4.6, matched comparison&lt;/td>
&lt;td style="text-align:right">7,776&lt;/td>
&lt;td style="text-align:right">105.49&lt;/td>
&lt;td style="text-align:right">70.61&lt;/td>
&lt;td style="text-align:right">76.25&lt;/td>
&lt;td style="text-align:right">32.06&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The bend appeared again in the fresh Sonnet 5 data. But the effect did not disappear at $H=2$: the $Z(2)$ and $Z(3)$ values were still enormous. Sonnet 4.6 also showed a very similar bend.&lt;/p>
&lt;p>This makes the result much less exciting than the huge numbers initially suggest. Sonnet 4.6 might also be watermarked, so it is not a true negative control, but it does seem the pattern is not unique to Sonnet 5 and does not look like a clean context-window boundary. The most likely explanation is that words like &lt;code>red&lt;/code> and &lt;code>green&lt;/code> naturally change how Claude chooses among fruits.&lt;/p>
&lt;p>So this was a strong detection of a prompt effect, but not a positive detection of SynthID. It also doesn&amp;rsquo;t rule out a different watermark that this test cannot see.&lt;/p>
&lt;h1 id="conclusions">Conclusions&lt;/h1>
&lt;p>My current best guess is that Anthropic is using a private-key watermark that changes token selection as Claude generates text. But that guess comes mostly from Anthropic’s description and negative results in other tests as opposed to a positive result in my experiments.&lt;/p>
&lt;p>I was able to rule out a few things as I found no evidence of hidden Unicode or whitespace, and the constrained-choice tests argue against a large, stable Green/red bias. That said, the apparent SynthID signal turned out to be a likely strong prompt effect that also appeared in Sonnet 4.6, so it doesn&amp;rsquo;t necessarily positively identify a watermark.&lt;/p>
&lt;p>Note that I&amp;rsquo;m not actually sure whether the watermarking rollout is fully complete yet and which models it&amp;rsquo;s available on. From Anthropic&amp;rsquo;s own help center article, it says that models are going to be watermarked going forward and that support for any existing model is &amp;ldquo;in progress&amp;rdquo;. I think I&amp;rsquo;ll have to re-run this analysis again in a few weeks or when there&amp;rsquo;s a verifiable model that does have watermarking enabled and is confirmed by Anthropic. We&amp;rsquo;ll just have to wait and see.&lt;/p>
&lt;h1 id="update-2026-08-20-anthropic-confirms-its-synthid-text">UPDATE (2026-08-20): Anthropic confirms it&amp;rsquo;s SynthID-Text&lt;/h1>
&lt;p>Well, we didn&amp;rsquo;t have to wait very long. Two days after I published this post, Anthropic put out a &lt;a href="https://www.anthropic.com/news/claude-text-watermark">blog post&lt;/a> with actual technical details (covered by &lt;a href="https://techcrunch.com/2026/08/15/anthropic-shares-more-details-about-how-claudes-new-watermarks-will-work/">TechCrunch&lt;/a> among others). Anthropic notes that Claude&amp;rsquo;s watermark is based on SynthID-Text, just as was predicted by this post. It&amp;rsquo;s nice to get one right occasionally!&lt;/p>
&lt;p>Going through what Anthropic confirmed point by point:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>It&amp;rsquo;s a keyed statistical watermark on token selection.&lt;/strong> In Anthropic&amp;rsquo;s words: &amp;ldquo;Instead of using an arbitrary random number generator to pick the next word, watermarking uses the key and a few words that come before to settle what word the model should pick.&amp;rdquo; That&amp;rsquo;s the same mechanism from the SynthID-Text section above.&lt;/li>
&lt;li>&lt;strong>No hidden characters.&lt;/strong> Straight from Anthropic: &amp;ldquo;Nothing is added to the text and there are no hidden characters.&amp;rdquo; This matches the Unicode and whitespace analysis above (where my analysis of 7.2 million characters turned up nothing)&lt;/li>
&lt;li>&lt;strong>Paraphrasing defeats it.&lt;/strong> Light editing preserves the watermark, but larger rewrites where a large number of words are adjusted will remove the watermark. This is consistent with my note above that a paraphraser sidesteps this watermarking fairly easily.&lt;/li>
&lt;li>&lt;strong>No performance cost.&lt;/strong> No extra tokens, no added latency, and (per DeepMind&amp;rsquo;s original Nature results) no statistically significant quality difference.&lt;/li>
&lt;li>&lt;strong>A detection API is coming.&lt;/strong> This one is a fun piece of new information. Anthropic says they will &amp;ldquo;soon be offering a watermark detection API,&amp;rdquo; with details still being worked out. They also state the watermark can&amp;rsquo;t be traced back to a specific person, organization, or chat. I&amp;rsquo;d bet that you&amp;rsquo;ll be able to pass text to their API, they&amp;rsquo;ll run an analysis using the secret key, and then they&amp;rsquo;ll give you the confidence / probability they have that it was indeed watermarked by Claude.&lt;/li>
&lt;/ul>
&lt;p>I also went ahead and re-ran the completed Sonnet 5 experiments on August 20, collecting 11,676 fresh responses with the same prompts and analysis as the August 11–12 archive. The short version is that Sonnet 5&amp;rsquo;s behavior changed substantially between the two runs, but the results did not necessarily change the original analysis much:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Probe&lt;/th>
&lt;th style="text-align:right">Archived result&lt;/th>
&lt;th style="text-align:right">August 20 re-run&lt;/th>
&lt;th>Reading&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Compact-digit red/green&lt;/td>
&lt;td style="text-align:right">p = 0.6769&lt;/td>
&lt;td style="text-align:right">p = 0.2204&lt;/td>
&lt;td>Negative in both runs&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Space-separated red/green&lt;/td>
&lt;td style="text-align:right">p = 0.5558&lt;/td>
&lt;td style="text-align:right">p = 1.0000&lt;/td>
&lt;td>Negative in both runs&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Fixed sampling&lt;/td>
&lt;td style="text-align:right">300/300 unique&lt;/td>
&lt;td style="text-align:right">300/300 unique&lt;/td>
&lt;td>No collisions in either run&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Context shielding, Z(H=1/2/3)&lt;/td>
&lt;td style="text-align:right">85.77 / 61.90 / 33.35&lt;/td>
&lt;td style="text-align:right">84.25 / 59.46 / 32.73&lt;/td>
&lt;td>Basically the same shape as the original experiments&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>There was nevertheless very strong drift from early August. Only 65.17% of the compact-digit choices, 58.44% of the spaced-digit choices, and 80.94% of the context-shielding choices exactly matched their archived counterparts. Paired randomization tests were at the Monte Carlo floor (p = 1/100001) for all three datasets. Reported median output-token counts also moved from, which would suggest that token accounting or effective tokenization changed as well.&lt;/p>
&lt;p>So something in Sonnet 5&amp;rsquo;s serving, sampling, tokenization, or surrounding configuration definitely changed. What did &lt;em>not&lt;/em> appear was a new watermarking signature that lets me attribute that movement to SynthID-Text. Anthropic says support for pre-August 2 models will be added over the coming months, and it has not published a known-positive backport date for Sonnet 5. A confirmed watermarked endpoint or the promised detection API is still needed to close that loop.&lt;/p>
&lt;h1 id="a-note-on-the-future-of-watermarking">A note on the future of watermarking&lt;/h1>
&lt;p>While this is mostly a technical post, I do think it&amp;rsquo;s worth thinking about what this potentially means for the future. It&amp;rsquo;s already relatively easy to detect when AI was used to write something and someone was careless. For example, I don&amp;rsquo;t need a statistical measure to figure out that this was written by an LLM: &amp;ldquo;That&amp;rsquo;s not a documentation problem — it&amp;rsquo;s a retrieval problem.&amp;rdquo;&lt;/p>
&lt;p>In my view, putting statistical watermarks like the one described in this post on all LLM output greatly ratchets up the stakes from what is easily perceptible by humans, and in a way that is particularly undemocratic. You&amp;rsquo;ll only be able to detect the watermark if you&amp;rsquo;re in a select group that has access to a secret key (e.g. frontier lab employees or government / police). While this particular change is somewhat innocuous in my opinion, as I would assume most content written in the years after 2026 will be LLM generated or at least LLM assisted, it is a bit scary to know that a single relatively undemocratic, but innocuous change can give way to many more that may not be as innocuous. The EU transparency code that Anthropic is following has basically mandated that watermarking of text is required from model providers operating in the EU, so unfortunately, we should expect this to happen to a lot more of our model output.&lt;/p>
&lt;p>Thankfully, sidestepping this kid of watermarking is fairly easy with a paraphraser or rephraser that doesn&amp;rsquo;t have a watermark (or just rewriting the text by hand). The watermarking is more meant to raise the cost and annoyance of doing so.&lt;/p>
&lt;h1 id="footnotes">Footnotes&lt;/h1>
&lt;p>[0] Of course, I tried to use Fable 5 for the analysis to start with, but it failed the security classifier and fell back to Opus 5 and I had to rely on the old trusty GPT-5.6-sol. This was probably better anyways as I&amp;rsquo;m not sure Claude would want itself to be self inspected.&lt;/p></description></item><item><title>Why we built 143</title><link>https://johnjwang.com/post/2026/06/30/why-we-built-143/</link><pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/06/30/why-we-built-143/</guid><description>&lt;p>The best person to understand a problem really deeply usually isn&amp;rsquo;t an engineer, it&amp;rsquo;s usually someone who&amp;rsquo;s using the product day in and day out with customers. Or it&amp;rsquo;s the customer support person who sees questions all day about why a particular feature isn&amp;rsquo;t working. While engineers have historically been the only people who could fix things, that&amp;rsquo;s not true anymore.&lt;/p>
&lt;p>Now with coding agents, non-engineers can fix things too and tend to be closer to the problems that users run into on a daily basis. The problem is that the tools built on top of these agents weren&amp;rsquo;t made for that person, they were built for engineers by engineers. That&amp;rsquo;s why we built &lt;a href="https://143.dev">143&lt;/a>.&lt;/p>
&lt;h1 id="where-it-started">Where it started&lt;/h1>
&lt;p>At Assembled, we saw this firsthand: our support and product teams kept surfacing fixes that engineers never had time for. Coding agents could have handled many of them, if the tooling didn&amp;rsquo;t assume you lived in a terminal.&lt;/p>
&lt;p>143 is the internal coding agent infrastructure we built at &lt;a href="https://www.assembled.com">Assembled&lt;/a> to help our non-engineers with this problem (while also helping our engineers build better software). We wanted coding agents to help with real product work, not just demos and internal tools.&lt;/p>
&lt;h1 id="what-we-built">What we built&lt;/h1>
&lt;p>We started with a small tiger team that cleaned up our instructions, invested more in CI/CD, built agent hooks, and made the agent environment less fragile. All of that helped, but it also made the bigger issue obvious: we needed a system that made this work shared across the team as opposed to being trapped inside each engineer&amp;rsquo;s terminal.&lt;/p>
&lt;p>We were inspired by internal systems like Stripe Minions and Ramp Inspect, but those were never available to the public. We wanted something open source that other teams could use, adapt, and improve.&lt;/p>
&lt;p>We built 143 so the person who spots the bug doesn&amp;rsquo;t need to become an engineer to fix it. That meant:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Automations shouldn&amp;rsquo;t be hidden on one engineer&amp;rsquo;s laptop&lt;/strong>, so anyone on the team can see what&amp;rsquo;s running and what changed.&lt;/li>
&lt;li>&lt;strong>Teams should be able to swap out intelligence and harnesses&lt;/strong> as coding agents and models improve.&lt;/li>
&lt;li>&lt;strong>Shared context should make it natural to start work automatically&lt;/strong> from Sentry issues, Linear assignments, PR comments, or scheduled checks.&lt;/li>
&lt;li>&lt;strong>Code review should be handled by agents&lt;/strong> on some or all PRs, and they should be able to auto-approve low-risk changes against thresholds you define.&lt;/li>
&lt;li>&lt;strong>You should be able to set up a great environment once for everyone&lt;/strong>, with the same repos, credentials, tools, logs, docs, and product context available to the whole team.&lt;/li>
&lt;/ul>
&lt;h1 id="open-source-for-everyone">Open source for everyone&lt;/h1>
&lt;p>The same idea that you shouldn&amp;rsquo;t have to be an insider to contribute is why we open-sourced 143.&lt;/p>
&lt;p>I owe a lot of my career to early open-source work on Ruby on Rails. That is where I learned software fundamentals from people like Aaron Patterson, Santiago Pastorino, Jose Valim, and Jeremy Doerr. Their PR reviews, their patience, and their willingness to design-pair with strangers on the internet shaped how I think about software.&lt;/p>
&lt;p>I was just a college student, but the Rails core team didn&amp;rsquo;t care who I was. If a PR was good and well-intentioned, it was welcome. I started with tests and tiny refactors, learned more of the codebase, and eventually got really deep into the internals of Active Record. That work helped me get my job at Stripe and became the launching pad for the rest of my career.&lt;/p>
&lt;p>I want 143 to be available in that same spirit. I hope it helps other people and teams the way open source helped me. The code is &lt;a href="https://github.com/assembledhq/143">on GitHub&lt;/a> under an MIT License.&lt;/p></description></item><item><title>Cheap software won't make engineering cheap</title><link>https://johnjwang.com/post/2026/05/31/cheap-software-wont-make-engineering-cheap/</link><pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/05/31/cheap-software-wont-make-engineering-cheap/</guid><description>&lt;p>In a world where AI writes more and more of the code, is it crazy to still want to be a software engineer? My answer is no. I think there will still be a reasonably large number of engineers in the future, and some of them will be incredibly well paid.&lt;/p>
&lt;p>I&amp;rsquo;m not necessarily saying there will be more of them than there are today. But if you&amp;rsquo;re an engineer (or whatever the future version of the job ends up being called) and you know how to build high-quality systems that solve real needs, you&amp;rsquo;re going to be very valuable.&lt;/p>
&lt;p>Two things seem likely to me, and both are already visible if you look at how other industries have evolved.&lt;/p>
&lt;h1 id="software-will-follow-jevons-paradox">Software will follow Jevons paradox&lt;/h1>
&lt;p>Jevons paradox is the observation that as something gets more efficient, we tend to use more of it, not less. &lt;a href="https://en.wikipedia.org/wiki/Jevons_paradox">William Stanley Jevons noticed&lt;/a> that when James Watt dramatically improved the steam engine, factories ended up burning more coal, not less. Cheaper power meant factories could produce more, businesses expanded their operations, and total coal consumption went up.&lt;/p>
&lt;p>It&amp;rsquo;s very likely that coding is going to get a lot cheaper. That means we&amp;rsquo;ll likely end up with far more software than exists today as it becomes cheaper and more possible to build. For example, every family might end up with its own custom app for running the household, or you might see every company customize their internal tools way more. Will professional software engineers be needed for all of this software? Probably not all of it, especially as it becomes easier and easier to write and maintain. But generally when markets expand, the need to have someone managing at least some of that software becomes pretty high.&lt;/p>
&lt;p>The other thing that I&amp;rsquo;ve noticed is that as things gets more efficient, the distribution of the thing tends to get broader and luxury goods tend to appear. More efficiency means more choice, and people sort themselves across the premium and the economy ends of the market.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Fashion.&lt;/strong> Most people can now afford a closet full of shirts and shoes. In the 1800s you used to only own a few pieces of clothing, but now manufacturing scale has made pretty much all clothes incredibly cheap. That has allowed the development of ultra-high end clothing: &lt;span class="no-math">handmade suits, $200+ merino wool t-shirts, $5k+ jackets, etc.&lt;/span>&lt;/li>
&lt;li>&lt;strong>Air travel.&lt;/strong> Similarly, as planes got more efficient over the decades, the cost of a ticket dropped precipitously and more people fly than ever before. But at the same time, the distribution of what it looks like to fly is wider than ever before. We now have basic economy seats where you can&amp;rsquo;t bring a carry on. But you also have first class suites and private jets. There&amp;rsquo;s much more dispersion than ever before.&lt;/li>
&lt;/ul>
&lt;p>I think software engineering will play out the same way. You&amp;rsquo;ll have a lot more software than there used to be, and you&amp;rsquo;ll also have a high end that is far higher end than it ever was. The handful of people who still know how to build hardened production software, systems that scale to massive levels of compute, stay reliable, and get the tradeoffs right, will be even more in demand than they are today. The middle falls away and you get a bimodal distribution, much like air travel: either you&amp;rsquo;re paying tens of thousands of dollars for the first-class or private experience, or you&amp;rsquo;re in economy.&lt;/p>
&lt;h1 id="engineers-will-orchestrate-more">Engineers will orchestrate more&lt;/h1>
&lt;p>The other shift is in actual job that will be done by engineers. I recently read &lt;a href="https://simpleflying.com/what-pilots-actually-do-14-hour-flight-autopilot-handleing-everything/">what pilots actually do on a 14-hour flight&lt;/a>, which is a fascinating corollary to what I think will happen in software.&lt;/p>
&lt;p>In commercial flights, the autopilot handles the flying of the plane on basically the entire flight, and the pilots physically fly the plane for only takeoff and landing. But the pilots&amp;rsquo; main jobs have shifted to handling communication with air traffic control, managing flights paths to look out for weather and turbulence, and handling contingency planning to develop a safe backup plan for each scenario. Arguably this is something that pilots could do before, but they&amp;rsquo;re likely much better now that it&amp;rsquo;s their main focus. Notice too that the job has switched from a in-the-zone, focused task of flying the plane to something that is much more interrupt and monitoring based.&lt;/p>
&lt;p>This is roughly what I expect for software engineers as the act of writing code keeps getting automated.&lt;/p>
&lt;p>There are a lot of articles making this case, but the general thesis is that engineers will spend their time on everything in the stack other than the pure implementation: the product requirements, the design, overseeing the implementation, making sure there&amp;rsquo;s enough testing, the rollout, the maintenance, talking to customers.&lt;/p>
&lt;p>We&amp;rsquo;ve seen this type of morphing happen before. In &lt;a href="https://www.youtube.com/watch?v=bWyOyyrVIXk">an interview with Cursor&amp;rsquo;s co-founder&lt;/a>, Simon Eskildsen (creator of Turbopuffer and Logrus, and a deeply skilled infrastructure engineer) describes how in the early 2010s you started to see DevOps engineers emerge: people who could both SSH onto a machine and write configuration. Before that, ops was its own role, people who managed the servers but didn&amp;rsquo;t write code. Over time that blended into what we now call production engineering: people who can code but also have deep expertise in Kubernetes, Terraform, AWS/GCP, observability, and logging. Now you don&amp;rsquo;t need as many people handling your devops, but the people who you still do need are way more valuable.&lt;/p>
&lt;p>I think the generalist engineer is about to go through a similar morph, just pointed in a different direction of some hybrid of engineer, product manager, and designer. The deep implementation skill hopefully won&amp;rsquo;t disappear, but it stops being the whole job.&lt;/p>
&lt;h1 id="so-will-the-future-be-good">So will the future be good?&lt;/h1>
&lt;p>I think there will be some ways in which the future is nicer, and other ways that will be extremely unfun.&lt;/p>
&lt;p>The future will be great because access to really custom software will likely get democratized. It&amp;rsquo;s going to be easy to have software that conforms much more exactly to what you specifically are looking for, and you&amp;rsquo;ll be able to build a lot of it yourself. The quality of life should keep climbing now that software can become more specifically built for you. I&amp;rsquo;m excited for things like access to better health information and much more customized health diagnoses that accessible much more readily. I&amp;rsquo;m also excited for much easier ability to talk across different languages as compute and translation become easier to put into devices.&lt;/p>
&lt;p>At the same time, the future might not be as fun because I think we&amp;rsquo;ll keep seeing stratification and a steadily rising Gini coefficient. The goods that are rival and zero-sum (housing in the places people want to live, access to really high quality education, etc.) derive their value from scarcity, so they don&amp;rsquo;t get cheaper as everything else does. They tend to do the opposite usually as a few people accumulate more wealth, which seems very likely in a world with more, cheaper software.&lt;/p>
&lt;p>So, the future will see a lot of change. I think the base layer of life will keep getting better and more customizable, while the scarce, positional stuff will keep getting harder to reach.&lt;/p></description></item><item><title>Time</title><link>https://johnjwang.com/post/2026/05/29/time/</link><pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/05/29/time/</guid><description>&lt;p>I&amp;rsquo;ve been thinking about time lately, especially how much of it is available. The strange thing I keep coming back to is that life feels both incredibly long and incredibly short at the same time, depending on which angle you look at it from. Both things can be true at the same time. It reminds me of the coastline paradox: a coastline wraps around a perfectly finite patch of land, yet the closer you measure it, the longer its edge gets, running off toward infinity the finer your ruler. It&amp;rsquo;s both finite and infinite at the same time, depending on how closely you look.&lt;/p>
&lt;h1 id="life-is-long">Life is long&lt;/h1>
&lt;p>Life expectancy in the United States is relatively long compared to 100 years ago. You can expect to live 76 years for males, 81 for females, and even these statistics are skewed downwards because of COVID deaths and drug overdoses, so if you&amp;rsquo;re a generally healthy person, you can expect to live &lt;a href="https://www.cdc.gov/nchs/products/databriefs/db548.htm">5-10 years longer than those baselines&lt;/a>.&lt;/p>
&lt;p>I&amp;rsquo;ve watched people have full-blown renaissances when they hit 40 or 50, and when you look closely it&amp;rsquo;s almost never out of nowhere: it&amp;rsquo;s compounding on a lifetime of work and learning that finally found its moment.&lt;/p>
&lt;p>There&amp;rsquo;s a long list of people who started their best-known company after 40: Eric Yuan (Zoom), Chip Wilson (Lululemon), Tony Fadell (Nest), Joseph Lubin (Ethereum). And in fact, most unicorn founders are actually in their &lt;a href="https://www.patreon.com/TheVentureMindset/shop/unicorn-report-466660?source=storefront">30s&lt;/a>, and the average one has &lt;a href="https://www.signalfire.com/blog/unicorn-founder-origins-data-report">14 years of industry experience&lt;/a> before founding, up from 8 years in 2010. Experience and network seem to be key components of making something very important, things you can only get from age.&lt;/p>
&lt;p>To me, it&amp;rsquo;s exciting because there are many examples of compounding in practice. The most famous example is probably Nvidia: Jensen Huang had been running Nvidia for 30 years before the LLM revolution, and he had spent that time quietly amassing a team and company filled with expertise and focused execution. That compounding was really unleashed when the AI revolution occurred and he was able to put Nvidia in exactly the right spot to capitalize on it&amp;rsquo;s expertise and moat.&lt;/p>
&lt;p>OpenAI looks similar, though on a shorter timespan. I remember when OpenAI was most famous for OpenAI Five, an AI system that played &lt;a href="https://openai.com/index/openai-five-defeats-dota-2-world-champions/">Dota 2&lt;/a> and defeated world champions. It was a toy at the time with no practical application, just like what they could GPT-3 and GPT-3.5 would be. They were only focused on developing great AI models, and that allowed them to compound their research advantage.&lt;/p>
&lt;p>My takeaway from this view is simple: keep learning and keep building. The runway is much longer than it feels in any given year.&lt;/p>
&lt;h1 id="life-is-short">Life is short&lt;/h1>
&lt;p>But the paradox is that even though life is long, our perception of time speeds up as we age. It&amp;rsquo;s a &lt;a href="https://pubmed.ncbi.nlm.nih.gov/16512313/">well-documented phenomenon&lt;/a>, usually attributed to two things a) the decreasing novelty of day-to-day life and b) the shrinking proportion of current time relative to everything you&amp;rsquo;ve already lived. A year is a tenth of a ten-year-old&amp;rsquo;s life and a fortieth of a forty-year-old&amp;rsquo;s, so of course it feels like it&amp;rsquo;s flying by.&lt;/p>
&lt;p>This means that if you&amp;rsquo;re only halfway through your life expectancy by the calendar, you&amp;rsquo;re actually much further than halfway through your perceived life. The clock and the felt experience are running at different speeds.&lt;/p>
&lt;p>Time also compresses when you&amp;rsquo;re heads down on something. Michael Siffre did &lt;a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC10115684/">a famous experiment&lt;/a> where he lived in a cave cut off from sunlight and clocks for months, and he experienced enormous time compression: he thought only about 150 days had passed when it had actually been closer to 180, and at one point counting to what he believed was 120 seconds took him 5 minutes. You can see a gentler version of this when a child is lost in coloring or when you surface from deep focus and realize hours are gone.&lt;/p>
&lt;p>Another reason why life is short is because the quality, health, and vigor you have at any given point of time declines. Your raw life force is generally strongest in your 20s and 30s. People in their 40s and 50s tell me constantly that they used to have way more energy. I didn&amp;rsquo;t want to believe it, but then I remembered that in my 20s, the 30-year-olds kept telling me my body would hurt more and injuries would take longer to heal, and I didn&amp;rsquo;t believe that either until it turned out to be completely true. On top of the energy curve, it generally gets harder to learn and grow into entirely new paths as you get older. Not impossible, just more effort than it took when you were younger. So you can have multiple things working against you at once.&lt;/p>
&lt;p>I&amp;rsquo;m in my 30s now, and I still have an incredibly active mind with more ideas than I can act on. But I&amp;rsquo;m just more tired than I used to be. It&amp;rsquo;s harder to stay up for long stretches, and a bad night of sleep hits me much harder than it once did. I suspect that only continues.&lt;/p>
&lt;h1 id="enjoy-it">Enjoy it&lt;/h1>
&lt;p>So life is both long and short, depending on the angle. Long enough that it&amp;rsquo;s never too late to start, and that compounding will reward patience. Short enough that the years you have the most energy and the most novelty are finite, and they&amp;rsquo;re quietly accelerating past.&lt;/p>
&lt;p>For me, I&amp;rsquo;m focusing on working on building things / working on problems I genuinely enjoy and continuing to learn from incredible people. I just hope to stop to smell the flowers every now and then.&lt;/p></description></item><item><title>Number of tokens shouldn't be the only metric</title><link>https://johnjwang.com/post/2026/05/06/tokens-shouldnt-be-the-only-metric/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/05/06/tokens-shouldnt-be-the-only-metric/</guid><description>&lt;p>I&amp;rsquo;ve heard of a lot of teams recently starting to use number of tokens as the key metric by which they measure their engineering team.&lt;/p>
&lt;p>It&amp;rsquo;s actually kind of funny that I even feel the need to write this blog post, but I did want to get it on record: I think it&amp;rsquo;s a bad metric if it&amp;rsquo;s your primary north star.&lt;/p>
&lt;p>Should it be one of many metrics that you use to understand how people on your team are performing? Yes. You definitely want some observability into how your engineers (or non-engineers) are using LLMs. But gamifying it and making it THE key metric is just a recipe for disaster.&lt;/p>
&lt;p>As I&amp;rsquo;m sure some companies have found out by now, there are a number of reasons why this isn&amp;rsquo;t a good idea:&lt;/p>
&lt;ul>
&lt;li>Tokens scale linearly with cost. While that may not be a problem early on, I guarantee you it will be a huge problem later on when you&amp;rsquo;re paying out the nose to Anthropic and OpenAI but can&amp;rsquo;t easily switch the volume off. Tokens tend to be reasonably sticky because it&amp;rsquo;s not easy to change workflows, especially if you have automations running that require tokens. Often it&amp;rsquo;s a project to go and identify where all the cost is coming from, categorize whether that cost is worthwhile, and then figure out how to stop it and possibly migrate systems off of LLMs.&lt;/li>
&lt;li>It&amp;rsquo;s a fast-tracked way to create an organization of Slop Cannons. If you are literally incentivizing tokens, then the incentive is for people to spend them as quickly as possible. Even if they&amp;rsquo;re not outright causing outages, low quality PRs being shipped into production can be slowly insidious over time. You&amp;rsquo;re incentivizing usage over anything else. More generally, tokens don&amp;rsquo;t tell you anything about whether the work was good. A 1M token agent run that fixes nothing looks identical on the dashboard to a 1M token agent run that ships a hard refactor. If your North Star metric can&amp;rsquo;t distinguish those two, your metric is lacking in a key dimension.&lt;/li>
&lt;/ul>
&lt;h1 id="but-i-want-people-to-use-ai-and-to-change-their-behavior">But I want people to use AI and to change their behavior!&lt;/h1>
&lt;p>Great, I do too, but the lesson I keep learning is that you can&amp;rsquo;t really skip the hard work that is required for behavior change.&lt;/p>
&lt;p>I think you should be optimizing for the people who are really excited to use AI and really putting them in charge of moving the organization, and then creating a wave of excitement about what&amp;rsquo;s possible now.&lt;/p>
&lt;p>The handful of people on your team who are already curious will figure things out faster than any incentive program will. Pair them with engineers who haven&amp;rsquo;t had their &amp;ldquo;aha&amp;rdquo; moment yet. Let them ship something visible. Run internal demos. Share war stories about workflows that went from hours to minutes. Behavior change happens through demonstrated value, not through KPIs denominated in tokens.&lt;/p>
&lt;p>The other thing worth saying: if your team isn&amp;rsquo;t using AI at the rate that you want, the problem is almost never that they need a quota. It&amp;rsquo;s usually that the tooling is rough, the workflows aren&amp;rsquo;t obvious, or nobody on the team has shown them what good looks like yet. None of those problems get solved by putting a token counter on the wall.&lt;/p>
&lt;h1 id="so-what-should-we-actually-look-at">So what should we actually look at?&lt;/h1>
&lt;p>If you want metrics, look at outputs rather than inputs. Some questions I&amp;rsquo;m asking our team:&lt;/p>
&lt;ul>
&lt;li>Are we shipping more product per engineer than we were six months ago?&lt;/li>
&lt;li>Are we resolving customer issues faster?&lt;/li>
&lt;li>Are people taking on projects they wouldn&amp;rsquo;t have attempted before?&lt;/li>
&lt;li>When engineers describe their week, do they sound more energized or more drained?&lt;/li>
&lt;/ul>
&lt;p>Tokens are an input, and the metrics that matter are almost always outputs. Optimize an input and you&amp;rsquo;ll get more of it, but you won&amp;rsquo;t necessarily get the thing you actually wanted.&lt;/p>
&lt;p>Should you watch token usage? Definitely! Use it for cost forecasting, for understanding adoption curves, for spotting people who might benefit from a nudge or some coaching. Just don&amp;rsquo;t make it the only thing that matters.&lt;/p></description></item><item><title>Why are executives enamored with AI but ICs aren't?</title><link>https://johnjwang.com/post/2026/03/27/why-are-executives-enabled-with-ai-but-ics-arent/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/03/27/why-are-executives-enabled-with-ai-but-ics-arent/</guid><description>&lt;p>I think there’s pretty clearly a divide in AI perception between executives and individual contributors (ICs). Executives seem to love it and evangelize it (going so far as to creating mandates at their companies for AI usage). But ICs are typically much more skeptical of its usage. You can see the divide show up everywhere from Hacker News comment threads to internal Slack debates about adopting coding agents.&lt;/p>
&lt;p>Here&amp;rsquo;s my current posit for why there&amp;rsquo;s such a big divide: executives have always had to deal with non-determinism and focus on nondeterministic system design, while individual contributors are evaluated by their execution on deterministic tasks.&lt;/p>
&lt;h1 id="managing-non-deterministic-systems">Managing non-deterministic systems&lt;/h1>
&lt;p>Executives have always had to deal with non-determinism. That’s par for the course:&lt;/p>
&lt;ul>
&lt;li>People being out sick or taking time off unexpectedly&lt;/li>
&lt;li>Someone not finishing an important project and not talking about it until far too late in the process&lt;/li>
&lt;li>People reacting to an announcement in an unexpected way&lt;/li>
&lt;li>A feature being built in a way that doesn&amp;rsquo;t make sense with respect to the rest of the product, but does technically achieve objectives.&lt;/li>
&lt;/ul>
&lt;p>More generally, if you&amp;rsquo;ve ever taken a Chaos Theory class in math, you&amp;rsquo;ll know that nonlinear, chaotic systems emerge when individual agents in a system are all acting with different inputs, utility functions, etc. Systems become slightly easier to manage if you&amp;rsquo;re able to make those utility functions consistent (you&amp;rsquo;re able to get a grasp on system dynamics).&lt;/p>
&lt;p>A manager&amp;rsquo;s job is to create a model of the world and align everyone&amp;rsquo;s utility functions, knowing that there&amp;rsquo;s a large amount of non-determinism in complex systems. So it makes sense that as a manager, you&amp;rsquo;re ok with a decent amount of this.&lt;/p>
&lt;p>AI is something that is non-deterministic but has a lot of characteristics of a well behaved chaotic system (specifically a system where you can understand the general behavior of the system, even if you cannot predict the specific outcomes at any point in time).&lt;/p>
&lt;p>For example:&lt;/p>
&lt;ul>
&lt;li>LLMs generally continue their work and provide an output regardless of time of day, how difficult the task is, how much information is available&lt;/li>
&lt;li>LLM&amp;rsquo;s deficiencies have well defined failure modes (e.g. hallucinations, lack of ability to operate outside of their context, and especially poor outcomes when not given enough context)&lt;/li>
&lt;li>The types of tasks that an LLM can accomplish are relatively well known, and the capability envelope is getting mapped out quickly. This is different than humans, where each person has a different set of strengths and weaknesses and where you need to uncover these over time.&lt;/li>
&lt;/ul>
&lt;p>Many of these properties are more deterministic than large human systems, which makes AI incredibly attractive for an executive who is already used to this and likely has put a large amount of effort into adding determinism into their systems already (e.g. by adding processes and structure in the form of levels and ladders, standard operating procedures, etc.).&lt;/p>
&lt;h1 id="ics-live-in-a-more-deterministic-world">ICs live in a more deterministic world&lt;/h1>
&lt;p>ICs are generally much more focused on particular problems that have specific inputs and outcomes. Correctness is easier to determine, and how good you are at your job can largely be described by quality and speed, where the weights on those two depend on which organization you&amp;rsquo;re in. This changes as you move up the ladder (a staff engineer is expected to tackle large, ambiguous business problems), but for most ICs, the world is relatively well defined.&lt;/p>
&lt;p>ICs deal with plenty of non-determinism in practice (unclear requirements, flaky systems, shifting priorities), but the way they&amp;rsquo;re evaluated pushes in the other direction. An IC&amp;rsquo;s value often comes from being reliably precise (e.g. writing correct code, getting the analysis right, producing a design that holds up under scrutiny). The more deterministic your output, the better you are at your job.&lt;/p>
&lt;p>AI introduces non-determinism into exactly this space, and from an IC&amp;rsquo;s perspective, there are good reasons to be skeptical:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>It&amp;rsquo;s not as good as they are at their job.&lt;/strong> A highly trained human focused on a specific task will often beat an LLM, especially if that task is long running, requires connecting multiple systems, or demands precise domain intuition. If you&amp;rsquo;re an expert and you&amp;rsquo;re handed a tool that does a mediocre version of your work, the overhead of fixing its mistakes can genuinely cost more than doing it yourself.&lt;/li>
&lt;li>&lt;strong>It changes what their job is.&lt;/strong> You go from doing the work yourself to managing something that does the work. The skills that got you hired (deep focus, precision, domain knowledge) aren&amp;rsquo;t necessarily the skills that make you good at that. That&amp;rsquo;s a disorienting shift.&lt;/li>
&lt;li>&lt;strong>It&amp;rsquo;s tied to self worth.&lt;/strong> Work accounts for the majority of a person&amp;rsquo;s waking hours. When executives talk about AI making everyone more productive, ICs can hear that as the things you&amp;rsquo;ve spent years getting good at are about to matter less. Whether or not that&amp;rsquo;s what&amp;rsquo;s actually being said, it&amp;rsquo;s a reasonable thing to feel.&lt;/li>
&lt;/ul>
&lt;p>One note: organizations that bias towards speed over quality tend to see more IC adoption of AI (e.g. my network of engineers at startups are on the whole adopting AI and using it to speed quite a few things up, though not necessarily making things higher quality). Organizations that bias towards quality often see the opposite. AI doesn&amp;rsquo;t really make quality higher, or it&amp;rsquo;s quite difficult to make it do so, and it can sometimes make quality on specific tasks worse because these ICs are typically really well trained for their specific task.&lt;/p>
&lt;h1 id="so-where-does-the-friction-come-from">So where does the friction come from?&lt;/h1>
&lt;p>The difference in AI perception comes down to what work looks like at different parts of the stack. Executives manage non-deterministic systems and have built their careers around it. ICs operate in a more deterministic world and are evaluated on their ability to deliver precise, reliable output. AI fits neatly into the first worldview and awkwardly into the second.&lt;/p>
&lt;p>I think this framing explains a lot of the friction that shows up when companies try to roll out AI adoption broadly. The same tool looks fundamentally different depending on what your job actually asks of you.&lt;/p></description></item><item><title>Mamba-3</title><link>https://johnjwang.com/post/2026/03/21/mamba-3/</link><pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2026/03/21/mamba-3/</guid><description>&lt;p>Mamba-3 just dropped yesterday. It&amp;rsquo;s a big milestone towards unseating the stranglehold that transformers have on the modern AI industry.&lt;/p>
&lt;p>Mamba-3 is a state space model, and it&amp;rsquo;s fascinating because it uses an entirely different architecture from transformers (the tech that the big LLMs like Opus 4.6, GPT 5.4, Gemini 3, etc. are based on).&lt;/p>
&lt;p>Transformers keep a huge memory layer called the KV cache: this essentially stores all the memory of everything previously said in a conversation when it is computing the next token. It needs this because that ability to look at previous history is core to how it&amp;rsquo;s able to reason well on large volumes of input data (this is called self-attention).&lt;/p>
&lt;p>The downside of a transformer is that as you increase the number of inputs (the prefill phase where it&amp;rsquo;s reading your system prompt) and outputs (the decoding phase where it&amp;rsquo;s generating text), you&amp;rsquo;re increasing the KV cache with each new token. This means by default that transformers are quadratic in their memory constraints, so large inputs slow these models down dramatically over time. Of course the big labs have figured out clever ways to improve performance here, but the math of the base transformer still slows down over time.&lt;/p>
&lt;p>Modern state space models (like Mamba) use a very different approach: they keep a single fixed-size hidden state $h$ that adjusts over time: $h_t = A_t \, h_{t-1} + B_t \, x_t$ (where $A_t$ and $B_t$ are data-dependent matrices generated on the fly based on the current input vector $x_t$). This allows the model to selectively choose what to remember and what to forget.&lt;/p>
&lt;p>There&amp;rsquo;s a few magical things about state space models:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>They&amp;rsquo;re much more efficient over long context because computation grows linearly in size (instead of quadratically). This is perfect for audio because there&amp;rsquo;s a huge amount of data in an audio file, much more than in text. This is one major reason why Cartesia is a leader in the audio space (their lab pioneered the modern state space models).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>State space models can use linear algebra tricks to compute the prefill phase incredibly quickly. Notice that $h_1 = A_1 \, h_0 + B_1 \, x_1$ and $h_2 = A_2 \, h_1 + B_2 \, x_2$. This means that you can actually entirely skip the computation of the hidden state $h_1$ if you just use a bit of algebra:&lt;/p>
$$h_2 = A_2 \, A_1 \, h_0 + A_2 \, B_1 \, x_1 + B_2 \, x_2$$
&lt;p>Previously, you would need to compute each token and feed that in as input into the next token, but with state space models, you can skip that and compute the last hidden state immediately. Then when you get to the decoding phase where you&amp;rsquo;re actually doing inference on the new tokens, the state space models switch over to computing the hidden states one at a time.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Mamba-3 in particular does some really interesting stuff to make inference more efficient. I think the team has correctly recognized that there&amp;rsquo;s a big shift happening in the world of AI: as coding models and LLMs more generally start to run larger and larger workloads, inference has started to become a bigger percentage of GPU usage. It used to be that labs would spend the majority of their GPU fleet on research and training, but now that AI is out in the wild and being used quite extensively, inference is much more important.&lt;/p>
&lt;p>Mamba-3 has a few optimizations for this:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Multi-input, multi-output.&lt;/strong> Previous generations of Mamba models would calculate the output tokens one at a time, similar to what most transformer-based architectures do. But the researchers noticed that GPUs are mostly bottlenecked on moving memory from VRAM to the compute cores. So, they restructured the math to group multiple state updates together into a big matrix multiplication, forcing the GPU to do more math at once while it waits.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Complex numbers for memory.&lt;/strong> If you apply a real number multiple times, it can only go up or down. For example, if you multiply something by $0.9$ many times, that number will tend to zero. If you multiply by $1.1$ many times, that number will tend towards infinity. One problem of previous Mamba models was that if your memory only contains real numbers, you&amp;rsquo;ll either definitely forget something or definitely remember something given sufficient time.&lt;/p>
&lt;p>Mamba-3 adds complex numbers to its memory, which can rotate in space. For example if you multiply $1$ by $i$ multiple times, you get back to $1$ after 4 multiplications: $1 \cdot i = i$, $\; i \cdot i = -1$, $\; {-1} \cdot i = -i$, $\; {-i} \cdot i = 1$.&lt;/p>
&lt;p>This means that Mamba-3 has the ability to track cycles, oscillatory patterns, etc.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>It seems like the big labs are still mostly optimizing transformers, but hybrid models like AI21&amp;rsquo;s Jamba and Google&amp;rsquo;s Griffin already exist, and I bet that the next wave of models combining Mamba blocks and transformer blocks will be just around the corner.&lt;/p></description></item><item><title>Five opinions on building things well</title><link>https://johnjwang.com/post/2023/10/23/five-opinions-on-building-things-well/</link><pubDate>Mon, 23 Oct 2023 00:00:00 +0000</pubDate><guid>https://johnjwang.com/post/2023/10/23/five-opinions-on-building-things-well/</guid><description>&lt;p>I sometimes cringe at sharing my opinions (who cares about my opinions anyways), but I keep these around because back in college a similar &amp;ldquo;Opinions&amp;rdquo; section actually started some awesome conversations, so maybe it will in the future too. (These previously lived on a standalone page of this site — the first four date to October 2023, and the last was added in November 2025.)&lt;/p>
&lt;h1 id="stay-somewhere-long-enough-to-see-legacy-code">Stay somewhere long enough to see legacy code&lt;/h1>
&lt;p>Most engineers change jobs frequently, but the best engineers I&amp;rsquo;ve known tend to stay somewhere for a long time. It can be difficult seeing your peers move to exciting, flashy companies with big salaries and titles, but I&amp;rsquo;ve found that staying in one place gives you deep wisdom and perspective.&lt;/p>
&lt;p>The caveat here is that you need to find a good company (somewhere that is growing and where you trust the leadership team). If you&amp;rsquo;re able to find that, then:&lt;/p>
&lt;ul>
&lt;li>You&amp;rsquo;ll learn how your decisions turned out. One of the key parts to learning is having a feedback cycle. If you don&amp;rsquo;t stay at a company long enough, you&amp;rsquo;ll never be able to see how the software you built turns out (whether good or bad).&lt;/li>
&lt;li>You&amp;rsquo;ll constantly evolve yourself as the company changes. You&amp;rsquo;ll tend to be provided opportunities as a company grows that you might not have gotten if you were a new hire somewhere else.&lt;/li>
&lt;li>You&amp;rsquo;ll gain confidence in making things happen. As you spend time building in your current environment, you&amp;rsquo;ll get better at it and start to understand what it takes to ship a product or feature.&lt;/li>
&lt;/ul>
&lt;h1 id="creativity-should-go-to-the-right-place">Creativity should go to the right place&lt;/h1>
&lt;p>If you look at any of the tables that are still around from hundreds of years ago, you&amp;rsquo;ll notice they&amp;rsquo;re typically made the same way: mortise and tenon construction. Mortise and tenon joinery is simple and straightforward, but also strong and long-lasting. It&amp;rsquo;s been the gold standard for table construction for thousands of years.&lt;/p>
&lt;p>The interesting thing is that while the construction method is typically the same, the style of antique furniture can be wildly different: from extremely ornate federal style furniture with marquetry and inlays of the 1700s to large, craftsman style pieces from the early 1900s.&lt;/p>
&lt;p>Likewise, I believe the key to building timeless software is to build the bones of your system in a standard way, and to use your creativity in other areas. This means sticking with battle tested tooling (e.g. PostgreSQL) and innovating on solving user problems with your product.&lt;/p>
&lt;h1 id="its-not-speed-vs-quality-its-speed--quality">It&amp;rsquo;s not &amp;ldquo;Speed vs. Quality&amp;rdquo;, it&amp;rsquo;s &amp;ldquo;Speed + Quality&amp;rdquo;&lt;/h1>
&lt;p>I think the biggest determinant of quality is the skill of the craftsperson, not the amount of time someone spends focusing on quality. On the margins, it&amp;rsquo;s true that if you spend more time on something, the output will tend to be higher quality.
But I also think a skilled craftsperson tasked with creating a table is going to take far less time and produce a higher quality product than an unskilled craftsperson who is focusing extensively on the quality of the outcome.&lt;/p>
&lt;p>In my belief, skill and expertise are such overriding determinants of final build quality that I think we should talk about the &amp;ldquo;Speed + Quality&amp;rdquo; combination, i.e. becoming more skillful so that you can finish things faster AND with higher quality.&lt;/p>
&lt;p>Here&amp;rsquo;s an example: &lt;a href="http://www.strazzafurniture.com/">Frank Strazza&lt;/a>, a well-known master woodworker, put on a dovetail demonstration at the &lt;a href="https://texaswoodworkingfestival.com/">Texas Woodworking Festival&lt;/a> where he finished a set of half-blind dovetails in 15 minutes. The end result was far more pristine and high quality than something that would&amp;rsquo;ve taken an amateur woodworker over an hour to finish.&lt;/p>
&lt;p>You&amp;rsquo;ll notice this in all disciplines: speed and quality are inherently linked. If you&amp;rsquo;re an amateur, you likely don&amp;rsquo;t have the ability to create something high quality yet. As you become more experienced, your work becomes higher quality because of your methods, tools, and general knowledge. It becomes easier and faster for you to complete work. At the same time, your minimum quality bar also increases and the work you output by default is higher quality.&lt;/p>
&lt;p>Software engineering is no different. Take a look at Russ Cox&amp;rsquo;s &lt;a href="https://github.com/rsc/pdf">PDF parsing library&lt;/a>. He wrote this over a few weekends because he needed to parse some PDFs. The resulting library is still in use in many codebases (including Assembled&amp;rsquo;s) and is considered one of the main libraries for parsing PDFs in Golang.&lt;/p>
&lt;p>All this is to say: build lots of stuff and continuously improve as you build. The more pieces of furniture you create, the more software you write, the better the overall quality of your output will be so long as you&amp;rsquo;re looking for feedback and constantly improving your techniques.&lt;/p>
&lt;h1 id="beta-fast-launch-slow">Beta fast, launch slow&lt;/h1>
&lt;p>At &lt;a href="https://www.stripe.com">Stripe&lt;/a>, there was a mantra that for new features, we should bring on beta users at 25% and launch at 98%. The idea was to focus early on product and idea validation, ensuring that you&amp;rsquo;re iterating as soon as possible with real users. This was paired with extremely high standards for a feature launch &amp;ndash; we only fully launched the product to the public once all the kinks had been removed.&lt;/p>
&lt;p>We use the same &amp;ldquo;Beta fast, launch slow&amp;rdquo; framework at Assembled to build high quality products that people actually want to use.&lt;/p>
&lt;h1 id="if-no-one-is-ever-mad-at-you-youre-probably-a-bit-too-risk-averse">If no one is ever mad at you, you&amp;rsquo;re probably a bit too risk averse&lt;/h1>
&lt;p>If you’re trying to do anything meaningful, someone is going to be annoyed, uncomfortable, or outright mad at you sooner or later. If literally no one is ever upset with you, it might be a sign that you’re avoiding hard conversations, difficult tradeoffs, or ambitious bets.&lt;/p>
&lt;p>When someone is mad, I’ve found it useful to pause and ask a couple of questions:&lt;/p>
&lt;ul>
&lt;li>Are they mad at a specific action I took (something I did carelessly, unfairly, or without enough context)?&lt;/li>
&lt;li>Or are they mad at what I represent (a change in direction, a standard I’m trying to uphold, a decision that breaks with the status quo)?&lt;/li>
&lt;/ul>
&lt;p>If they’re mad at my actions, there’s usually something I should fix, apologize for, or do better next time. If they’re mad at what I represent, there’s often at least a kernel of truth in the reaction, but it doesn’t automatically mean I should back down.&lt;/p></description></item></channel></rss>