# Abdul Rafay - Full Blog Content > Senior Full Stack Developer building production SaaS platforms, cross-platform mobile apps, and AI-integrated systems. Writing about software engineering, architecture, and the craft of shipping real products. --- # From Unlimited to Metered: How AI Coding Tool Pricing Actually Evolved - **URL**: https://www.rafay99.com/blog/from-unlimited-to-metered/ - **Published**: 2026-08-01 - **Author**: Abdul Rafay - **Tags**: AI, ThoughtsProcess, AICodingTools, ClaudeCode, OpenCode - **Description**: Copilot started with per-message pricing. Cursor promised unlimited. Now everything is token-based credits and rolling session windows. Here's how we got here — and why your subscription works the way it does. I've been thinking about this for months, and I think I finally have the story straight. There was a time when AI coding tool pricing was simple. You paid $10 or $20 a month, you got a fixed number of requests, and when you hit the limit, you waited or upgraded. That was it. No credit pools, no token math, no rolling session windows, no "this model costs 60x more than that model." That time ended in June 2025, and most developers still don't fully understand what replaced it. So let me walk through the whole arc — how we got from per-message pricing to the token-based, session-windowed, credit-pooled world we live in now. Because the only way to not get burned by these systems is to understand what they're actually measuring. ## Back when Copilot was the only game in town GitHub Copilot launched in June 2021 as a technical preview. The pricing was almost comically simple in hindsight: **$10/month for individuals, unlimited completions.** You paid, you got suggestions. There was no concept of "premium models" or "credits" because there was only one model — Codex — and it was cheap enough that GitHub could absorb the cost. When Copilot went GA in June 2022, the pricing hadn't changed. $10/month individual, $19/month for business. The value proposition was straightforward: autocomplete for your editor. The model was small enough, the inference cheap enough, that usage variance didn't matter. A heavy user might cost GitHub $3-4 in inference. A light user cost pennies. The $10 average covered everyone. This was the **flat-rate era**, and it worked because: - The model was a single, small model (Codex / early GPT-3 variants) - Output was short — a few lines of completion, not whole files - There was no agent mode, no multi-file editing, no tool calling - Inference costs were a fraction of what they are today The most expensive thing Copilot did was generate a function body. Compare that to today's agents that can rewrite your entire codebase, spawn sub-processes, and run for 15 minutes straight generating tens of thousands of tokens. The cost profile is unrecognizable. ## Then Cursor showed up and changed everything Cursor launched in 2023 and did something Copilot couldn't: it integrated *multiple* frontier models directly into the editor experience. Claude, GPT-4, and later Gemini and DeepSeek. The quality jump over Copilot was immediate and massive. But so was the cost problem. Cursor didn't own the models. Every time a user asked Claude Sonnet to refactor a file, Cursor paid Anthropic API rates. Every time a user asked GPT-4 to explain a codebase, Cursor paid OpenAI. Their margins were thin, and their pricing had to cover a much wider range of costs than Copilot ever faced. Initially, Cursor tried to keep the flat-rate model alive. **$20/month for 500 "fast" requests.** Unlimited "slow" requests (their own cheaper routing). Unlimited tab completions. This was essentially Copilot's model with a request cap bolted on — and for a while, it worked. But then three things happened simultaneously: **Models got more expensive.** Claude Opus, GPT-4 Turbo, and the reasoning models all came with dramatically higher per-token costs. A single Opus response doing multi-file reasoning could cost Cursor $0.50-$1.00 in inference. An agent mode session that ran for 10 minutes could cost $5-$10. **Users got agentic.** The introduction of Composer, Agent mode, and multi-file edits meant each "request" was no longer a simple Q&A. It was a sprawling, tool-calling, file-rewriting session that consumed 10-100x more tokens than before. The average cost per request skyrocketed. **The "unlimited" promise broke.** This is where I wrote my [Cursor's Pricing Shock](/blog/cursor-unlimited-ai-cost-shock) post, and honestly, nothing has changed my view since. Cursor promised "unlimited" for $20, and 12 days later, power users were getting $100+ bills. The math simply didn't work. The root cause was simple: **flat-rate pricing can't survive when your input costs vary by 60x per request.** Cursor had to change or bleed money. ### The June 2025 pivot In June 2025, Cursor replaced the 500-request model with **credit-based billing.** Your $20 plan now bought you $20 in API credits. Auto mode (Cursor's smart routing) was still unlimited. But manually selecting a premium model — Claude Sonnet, Opus, GPT-4 — would draw from your credit pool at varying rates based on actual API costs. The backlash was enormous. I covered the details — refunds, apology blog posts, community outrage — in my earlier post. But the important thing is what it represented: **the death of flat-rate pricing in AI coding tools.** Once Cursor admitted that one request wasn't equal to another, the era of simple pricing was over. The burn rate difference is the whole story. Haiku costs $0.25 per million input tokens. Opus costs $15. Same tool, same task format, 60x difference. A flat-rate plan can't price for both. ## Everyone followed suit — but differently After Cursor's pivot, the dominoes fell fast. The interesting part is how differently each tool implemented the same basic idea. **GitHub Copilot (June 2026):** After years of flat $10/month pricing, Copilot moved to usage-based billing with AI Credits. Pro now includes $15 in credits. Premium models (Opus-tier) consume credits at 3x the base rate. The Copilot ecosystem integration is still unmatched — it sees your issues, PRs, and CI results — but the pricing model converged with everyone else's. The interesting thing about Copilot's transition is how quietly it happened compared to Cursor's firestorm. GitHub has more users, a stronger brand, and better communication channels. They also had the benefit of watching Cursor take the arrows first. The lesson was learned: you need a dashboard, you need clear limits, and you need to grandfather users or offer opt-outs. **Claude Code (always been session-based):** Anthropic's pricing model was different from day one. No credits. No per-request limits. Instead, Claude Code uses **rolling session windows.** Your subscription gives you a certain amount of active usage time — typically measured in hours — on a rolling basis. The clock only ticks when Claude is generating tokens. Idle time doesn't count. This is the model that confuses people the most, so let me be specific. ### How rolling sessions actually work Imagine you have a 5-hour session window. That window is a bracket sliding forward through time. When you use Claude Code for an hour, that hour goes into the window. The window rolls forward continuously — typically on a multi-day cadence, depending on your plan. So if you use 4 hours on Monday and 1 hour on Tuesday, your available time on Wednesday depends on whether Monday's usage has rolled out of the window yet. It's not a monthly reset. It's a **rolling replenishment** — old sessions age out, new capacity opens up. The reason this matters: **people think they have a monthly budget, but they actually have a rate limit.** The $20 Pro plan gives you roughly 15-20 hours of active coding per month *at Sonnet speeds.* If you try to do that in a week, you'll hit the rolling window limit because the replenishment can't keep up with the consumption rate. The $100 Max plan expands the window and gives you Opus-tier reasoning. The $200 Max plan expands it further — effectively unlimited for daily use. Same software, same features, just more room in the window and a smarter model answering your prompts. **Windsurf (rebranded from Codeium):** Windsurf went with yet another model — **daily and weekly quotas** instead of monthly credit pools or rolling sessions. Your daily allowance resets every day. Your weekly allowance resets every week. This is the most predictable model for budgeting, but it's also the least flexible — you can't save up unused capacity or borrow from future allocations. **OpenCode and Command Code:** These tools operate on a fundamentally different axis. They don't use frontier models as their primary offering. They use **open-weight models** (DeepSeek, MiniMax, Hunyuan) that cost a fraction of what Opus or GPT-4 cost to run. This lets them offer aggressive pricing — Command Code's $1 Go plan, OpenCode's $5-10 Go plan — while staying solvent. The trade-off is model capability. DeepSeek V4 Flash is genuinely good at logic and debugging when pointed in the right direction. But it's not Sonnet 5. It's not Opus. You're trading raw intelligence for raw volume — more requests, cheaper models, different edge cases. ## The token economics underneath everything Underneath all the subscription plans and credit pools, there's a single layer that determines the real economics: **token pricing.** Every model has an API price. Every subscription is a wrapper around that price. Here's the ranges as of July 2026: | Model | Input (per MTok) | Output (per MTok) | Relative cost | |-------|-------------------|--------------------|---------------| | Haiku 3 | $0.25 | $1.25 | 1x (baseline) | | Sonnet 5 | $2.00 | $10.00 | 8x | | Opus 4.8 | $15.00 | $75.00 | 60x | | GPT-5.6 Luna | $1.00 | $6.00 | 4.8x | | GPT-5.6 Terra | $2.50 | $15.00 | 12x | | GPT-5.6 Sol | $5.00 | $30.00 | 24x | | DeepSeek V4 | $0.50 | $2.00 | 1.6x | These numbers are the floor. Every tool above them adds a margin, but they can't go below these costs for long. Now here's the part that matters for your wallet: **output tokens dominate the bill.** A typical agentic coding session might use 5,000 input tokens (your prompt + context) and generate 15,000 output tokens (the code, reasoning, file edits, tool calls). At Sonnet 5 rates, that session costs roughly $0.15 in input and $0.15 in output — $0.30 total. Run 100 of those in a month and you're at $30 in raw API cost, plus the tool's margin. At Opus 4.8 rates, the same 100 sessions cost roughly $7.50 in input and $11.25 in output — $18.75 total. But that's only the API cost. The tool still needs to add their margin, pay for infrastructure, and keep the lights on. Hence the $200/mo price tag for Opus-tier access. The math only makes sense if you're generating enough value per session to justify it. Most professional developers do. But understanding *why* the pricing works the way it does is the difference between feeling like you're getting ripped off and understanding the economics. ## Special pricing — Fable 5, promo rates, and the traps One thing I haven't touched yet is the **promotional pricing** that can temporarily break the normal economics. Fable 5 is the best example. Anthropic launched Fable 5 with a promotional window: **access included with Pro, Max, Team, and Enterprise plans at no extra charge.** For a period of time — extended multiple times as of this writing — subscribers could use Fable 5 for up to 50% of their weekly limits. The promo is currently set to expire on July 19, 2026, after which Fable 5 transitions to usage-based billing at $10/$50 per MTok. This is a different pricing model entirely. It's a **time-limited promotion** designed to: 1. Give users exposure to a new model without friction 2. Gather usage data and feedback 3. Convert users to paying API customers once the promo ends The key insight: **promotional pricing is designed for adoption, not sustainability.** The $10/$50 per MTok rate that Fable 5 will charge after the promo is the *real* price. The included access during the promo was a marketing cost. Similarly, Sonnet 5 launched with an introductory price of $2/$10 per MTok, running through August 31, 2026. After that, it's expected to settle at $3/$15. **Always check whether the price you're seeing is intro pricing or long-term pricing** — this distinction has burned a lot of people who budgeted based on launch prices. Other notable special cases: - **GPT-5.6 Sol usage limits were temporarily lifted** during the Codex and ChatGPT Work launches, giving all plans more access to the frontier model - **Cursor's Pro plan includes "bonus capacity"** beyond the $20 credit pool, but the exact amount is intentionally vague — it's a buffer, not a guarantee - **GitHub Copilot now supports session spend limits** — you can cap how much an agent spends in a single session, which is useful for controlling costs during heavy agent runs ## The patterns that actually explain everything After all this, I keep coming back to three patterns that explain almost every pricing decision in the space: **Fixed-cost plans die when variable-cost inputs diverge by 60x.** Copilot survived on flat-rate pricing because its model costs were narrow. Cursor, running 6+ models with wildly different API prices, couldn't. The credit pool model is the industry's answer to this: let users feel the variable cost directly, but give them a free option (Auto mode) to opt out when they don't need frontier reasoning. **Session-based billing aligns incentives better than credit-based billing.** Claude Code's rolling window charges for *time spent generating*, not tokens consumed or requests made. This means the model can be as verbose or concise as it needs to be without penalizing the user for seeking a thorough answer. Credit-based billing (Cursor, Copilot) creates a perverse incentive: users optimize for shorter responses to conserve credits, even when a longer response would be better. **Daily/weekly quotas are more predictable but less powerful.** Windsurf's daily and weekly quotas are the easiest to understand and budget around. You know exactly when your allowance resets. But you also can't front-load work — if you have a big coding session on Tuesday, you're limited by Tuesday's daily quota, not your remaining monthly budget. This predictability comes at the cost of flexibility. The usage curve is the real story. A 35% day followed by a 55% day exhausts your weekly capacity faster than you expect. The billing model determines whether that means "I need to wait for a rolling window" or "I can continue on Auto mode" or "I'm done for the day." ## So where does that leave us? I don't think we're going back to flat-rate pricing. The cost variance between models and use cases is too wide. But I do think the industry will settle into clearer norms — probably a combination of: a free/cheap tier with basic models, a $20 tier with credit-based premium access, and a $100-200 tier for unlimited usage of the best models. Until then, the best strategy is to understand which meter you're on, what you're actually being charged for, and when it resets. Because the tool doesn't care whether you understand the pricing — it just bills you. Until next time, go break something. --- ## References - [GitHub Copilot Plans](https://github.com/features/copilot/plans) - [Cursor Pricing](https://cursor.com/pricing) - [Anthropic Claude Pricing](https://www.anthropic.com/pricing) - [Cursor June 2025 Pricing Apology](https://cursor.com/blog/june-2025-pricing) - [Windsurf Pricing](https://windsurf.com/pricing) - [OpenAI Codex Documentation](https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan) - [OpenAI Codex Rate Card](https://help.openai.com/en/articles/20001106-codex-rate-card) - [Command Code Pricing](https://commandcode.ai/pricing) - [OpenCode](https://opencode.ai) - [CloudZero — Cursor AI Pricing 2026](https://www.cloudzero.com/blog/cursor-ai-pricing/) - [Developer Digest — AI Coding Tools Pricing Comparison 2026](https://www.developersdigest.tech/blog/ai-coding-tools-pricing-2026) - [GitHub Copilot Usage-Based Billing Guide](https://www.developersdigest.tech/blog/github-copilot-usage-based-billing-guide-2026) --- # Your AI Agent Isn't Getting Smarter. Its Harness Is. - **URL**: https://www.rafay99.com/blog/aiharnesss/ - **Published**: 2026-07-29 - **Author**: Abdul Rafay - **Tags**: AI, Harness, ClaudeCode, Codex, OpenCode, MCP, AgenticEngineering, ThoughtsProcess - **Description**: Everyone's arguing about which model tops the benchmarks. Nobody's talking about the thing that actually decides whether your agent works — the harness wrapped around it. Here's what's inside one, why it matters more than the model, and why you're already building them without knowing it. A few weeks ago I wrote [The Price of Thought](https://rafay99.com/blog/the-price-of-thought) — a post about how most people are wildly underusing these AI coding tools while somehow also overpaying for them. Near the end I dropped one line almost in passing: the real battleground in AI right now isn't the model, it's the *harness*. And then a bunch of you came into the comments and my DMs asking the same question, phrased about ten different ways: okay cool, but what actually *is* a harness? Fair. I blew past it. So this whole post is me going back and doing it properly. Here's the one sentence I want you to leave with, and honestly if you close the tab right after reading it I've still done my job: **The model is the engine. The harness is the car.** ## Why I keep saying the model is the boring part I know that sounds backwards. We've spent two years being trained to care about exactly one number — which model is on top of which leaderboard this week. GPT this, Claude that, some new open-weight model from China that just ate everyone's lunch. That's the conversation everybody's having. And it's the wrong conversation. Because a harness is the entire software system built *around* the model — all the stuff the model itself genuinely cannot do. Tool access. Memory. Permissions. Deciding what the model is even allowed to see. The loop that connects "the thing you typed" to "the model's answer" to "an actual change on your actual computer." The model is a brain in a jar. The harness is everything that gives that brain hands, eyes, and a memory. And here's the part people don't want to hear: the harness matters more than the model. I'm not saying that to be edgy. Look at what's actually happening in the wild. OpenAI built a production application with Codex — around a million lines — where *zero* lines were written by a human. Their engineers didn't write code. They spent their time designing constraints, docs, feedback loops, and lifecycle rules. In other words, they spent all their time on the harness. LangChain's DeepAgents jumped from 52.8% to 66.5% on a benchmark by changing *nothing* about the model — only the harness. And Vercel got better results by *deleting* 80% of the tools they'd handed their agent. Sit with that last one for a second, because it's the least intuitive and the most important. They made the agent *dumber* on paper — fewer tools, fewer options — and it got *better*. That is not a model story. That is a harness story from top to bottom. The model's intelligence is table stakes now. Everyone has a good-enough engine. The car you bolt around it is the whole game. ## So what's actually inside one? Let me strip the buzzwords off, because every serious AI system shipping in 2026 has some version of these pieces, whether the team calls it "a harness" or not. There are five parts, and once you see them you can't unsee them in any tool you use. **Permission and approval.** The most basic one, and the first one people skip when they roll their own. What is the agent allowed to do on its own, and when does it have to stop and ask you? Claude Code sits in a sandbox by default — it'll edit files freely but wants a nod before it touches the network or runs a command. Codex has the same idea with tiers: read-only, workspace-write, full access. This is the layer standing between you and an agent cheerfully running the one command that nukes your production database. It sounds obvious right up until it's 2am and it isn't there. **Context engineering.** Models have a finite window. The harness decides what goes in it and what stays out — summarising old conversation to free up room, spinning off sub-agents that go do a messy job and come back with a clean one-paragraph answer, loading instructions only when they're actually relevant. OpenAI's team found that a short `AGENTS.md` acting as a table of contents, pointing to deeper docs, beat one giant wall-of-text instruction file. Less in the window, more in the tank. **Tool orchestration.** Which external tools can the agent reach, how does it call them, and what happens when a call blows up? This is where MCP — the Model Context Protocol — comes in, the open standard for how agents discover and talk to outside services. And the big lesson here is the Vercel one again: less is more. Fewer tools, fewer redundant calls, fewer dumb detours. **Lifecycle hooks.** Little triggers that fire at specific moments. Lint after every edit. Check permissions before a command runs. Format on save. Run the tests before a commit lands. All the quality-control chores you'd otherwise be doing by hand after every single AI interaction — automated, so you stop being the linter. **System-level instructions.** `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.cursorrules` — the filename changes, the job is identical. A document that tells the agent how *your* specific project actually works. This is the cheapest, highest-leverage thing in the entire stack. A good project file can transform your output with zero lines of code. Stack all five up and it looks like this: Notice where the model sits — near the bottom, small, one box among many. That placement isn't me being disrespectful to the model. It's the actual architecture. ## The part nobody shows you: it's a loop Here's the thing that clicked for me and changed how I think about all of this. The harness isn't a passive wrapper you set up once. It's a runtime. It's *running* — cycling through the same stages — on every single prompt you send. You never see this. It's invisible by design. But every time you hit enter, the harness curates what the model gets to see, hands it over, reads the answer, checks it, goes and executes whatever the model asked for, feeds the results back, and loops until the job is done. The model never once reaches out and touches the outside world directly. The harness is its hands, its eyes, and its memory. Every time. ## Same model, different car This is the bit I've been repeating across three posts now and I'm going to keep repeating it: **same model, different harness, completely different output.** Claude Code's harness is tuned tightly around Anthropic's own models — its system prompt, its tools, its sub-agent setup, all built to make Claude specifically shine. OpenCode goes the opposite way: model-agnostic, swap providers mid-session, so its harness has to stay neutral and assume nothing about any one model's quirks. Codex behaves differently depending on whether you're in the CLI, the desktop app, or firing off a cloud task, because its harness is shaped by all that surface area. And sitting at the centre of every one of these is a system prompt — the real thing shaping how the agent behaves. It defines what tools exist, how they should be used, and the rules the agent must never break. These prompts started out short and generic a year ago. Today they're long, detailed documents about planning, tool use, when to ask you for clarification, and how to dodge the usual failure modes. Which is *why* an agent can feel noticeably better from one month to the next even when the model underneath it didn't change at all. The harness got better. Not the brain. The car. ## Harness, orchestrator, framework — these are not the same word People throw these three around like synonyms and they're not. Quick untangle: | Layer | Examples | The one-liner | | --- | --- | --- | | **Framework** | LangChain, LlamaIndex | The building blocks you assemble an agent out of | | **Orchestrator** | — | The reasoning loop — decides when to think, call, and act | | **Harness** | Claude Code, Codex, OpenCode | The hands *and* the operating system | | **Model** | Claude, GPT, DeepSeek, GLM | The engine. Raw intelligence. Table stakes. | Harnesses use frameworks. Orchestrators run inside harnesses. Together they turn a raw model into something that can actually do work. ## The most underrated job of a harness Here's the one that took me the longest to appreciate: the harness is what makes working *with* an AI actually bearable. A good one doesn't just run the model and dump the output on you. It stages the changes so you can look before you leap. It asks before it does something destructive. It shows you the diff and the test results. It watches how you correct it and adjusts. That's the whole line between "vibe coding" — where you shrug and accept whatever falls out — and real engineering with these tools. The harness is the translator sitting between what you meant and what the machine does, and then between what the machine did and something you can actually review and approve. Every time you eyeball a diff before committing, every time you write a `CLAUDE.md`, every time you approve or deny a tool call — you're not talking to the model. You're talking to the harness. ## So should you build your own? For almost everyone: no. And I say that as someone who loves building things from scratch to a fault. The CLIs and platforms that already exist are *very* good harnesses, and they're improving faster than you can hand-roll a worse one. The customisation hooks they give you — skills, plugins, connectors — let you bend them to your workflow without starting from zero. Here's the ladder I'd actually climb, in order: 1. **Start with a project config file.** A real `CLAUDE.md` or `AGENTS.md`. This one move can transform your output quality and it costs you nothing. It's a mini-harness. 2. **Then add skills.** Got a process you repeat constantly? Package it as a skill — an instruction file the agent loads on demand. No code. 3. **Then add hooks.** Want auto-lint after edits, tests before commits? Wire up hooks. Light infrastructure, real time saved. 4. **Only *then* think about a custom harness** — and only if you've genuinely outgrown the first three. The real reasons to: you need to orchestrate multiple models (say, one to plan and another to execute), you need domain-specific safety rails, or AI *is* your product. But here's the punchline, and it's the same one from *The Price of Thought* wearing a different shirt: **you're probably already building harnesses without calling them that.** Every system prompt you write, every skill you save, every connector you configure — that's you wrapping a model in infrastructure. The vocabulary is new. The practice is old. ## Wrapping up: stop buying engines If you take one habit away from this, make it this one: stop obsessing over which model benchmarked higher this week, and start paying attention to the car wrapped around it. When you pick between Claude Code, Codex, OpenCode, Cursor — you are not choosing a model. You're choosing a harness. Its system prompt, its permission model, its context handling, its tools, its hooks, its skills — *that's* what decides whether the thing works for your actual life. Two tools running the identical model will give you wildly different results because their harnesses are different. The intelligence is necessary. The harness is what makes it useful. The model is the engine. The harness is the car. Stop buying engines. Start choosing cars. --- *Do you think the harness matters more than the model, or am I overselling it? What's in your `CLAUDE.md` right now? Drop it in the comments — I actually want to argue about this. 👇* Until then, happy coding! --- # Code Is Cheap Now. Your Test Suite Is the Product - **URL**: https://www.rafay99.com/blog/code-is-cheap-now-your-test-suite-is-the-product/ - **Published**: 2026-07-25 - **Author**: Abdul Rafay - **Tags**: AI, Testing, CodeMigration, Rust, ClaudeCode, SoftwareEngineering, ThoughtsProcess - **Description**: Rewriting big software used to be unthinkable — feature parity was a wall you'd spend years climbing. Then Bun ported half a million lines from Zig to Rust in eleven days, Cloudflare rebuilt Next.js in a week, and Google let AI author 80% of a migration. The thing they all leaned on wasn't the model. It was the test suite. Here's why tests just became the most valuable code you own. ## The rewrite that never ends Let me start with the version of this story we're all used to — the sad one. System76 got tired of fighting GNOME. Their old Pop!_OS desktop was a pile of GNOME extensions, and every time GNOME shifted, those extensions cracked. So they made the big-boy decision: stop patching someone else's house, build your own. COSMIC — from scratch, in Rust, on Wayland, with their own toolkit. No GTK, no GNOME, no extensions. A clean thing they'd own end to end. That was 2021. The first alpha didn't land until August 2024. The first *stable* release didn't ship until December 2025. Four years to walk out of one desktop and into another — and honestly, that's a *success* story, because most from-scratch rewrites just die in the alpha. That's the world I grew up building in. Rewriting anything real was borderline irresponsible. The moment you said "let's rebuild this," you signed up to freeze features, freeze bugfixes, and freeze your roadmap while a team climbs the feature-parity wall for a year or three — and nobody thanks you, because from the outside nothing changed. The old thing already worked. You just spent eighteen months making a new thing that *also* works, if you're lucky. So we didn't rewrite. We patched, we wrapped, we suffered. The rewrite was the thing you dreamed about and never did. Then that rule quietly broke, and I don't think enough people have noticed. ## Exhibit A: half a million lines in eleven days I already [wrote a whole post about the Bun rewrite](https://rafay99.com/blog/bun-rewrite-zig-rust), so I won't re-run the whole thing here. Short version: Bun — the JavaScript runtime, ~22 million CLI downloads a month — got ported from Zig to Rust. **535,496 lines** of Zig across 1,448 files. **Eleven days.** One engineer watching a peak of **64 instances** of Claude do the typing. Read that again with the COSMIC timeline still warm. Four years to change a desktop. Eleven days to reimplement a production runtime in a different language. When I first read it, I did the thing everyone did — I got hung up on the model. *How is an LLM good enough to port half a million lines and have it actually run?* Wrong question. I said this in the Bun post and I'll say it louder here: the model is not the achievement. The rewrite is not the achievement. **The achievement is that they had a way to know it worked.** Jarred didn't type "rewrite Bun in Rust, don't make mistakes" and pray. He built a harness that treated every generated line as guilty until proven innocent — and the thing doing the proving was the test suite. The rule was blunt: nothing merges until 100% of the existing tests pass on the Rust side. Not most. All of them. The port wasn't "write Rust." The port was "make the Zig test suite green again in a language it's never seen." The Rust was almost a side effect. ## It wasn't a fluke. It's a pattern. If Bun were the only one, I'd call it a stunt. It isn't. **Cloudflare** rebuilt Next.js in a week. Not wrapped it — *rebuilt* it. `vinext` is a clean-room reimplementation of the Next.js API surface running on Vite instead of Turbopack, deploying to Workers. [Almost every line was written by Claude](https://blog.cloudflare.com/vinext/) driving through OpenCode, for about **$1,100** in tokens, by essentially one person steering. How do you clean-room a framework as sprawling as Next.js without shipping a thousand subtle behavior breaks? You don't hand-check it. They ported Next.js's own tests plus the OpenNext conformance suite and ran against it: **1,700+ Vitest unit tests, 380 Playwright end-to-end tests, 94% of the Next.js 16 API surface covered.** The suite *is* the spec. Hit the spec, you've built Next.js. (Hold onto that number — 94%, not 100% — and the fact that those tests proved *conformance*, not *security*. We're coming back to what that gap let through.) **Google** has been doing this at industrial scale since before it was cool. Their [AI code-migration writeup](https://research.google/blog/accelerating-code-migrations-with-ai/) is from 2024 and it already reads like the future: migrating IDs from 32-bit to 64-bit integers across *thousands* of files of C++ and Java, work that would've eaten "many software engineering years." A fine-tuned Gemini generated the edits; **80% of the changes were AI-authored**; total migration time dropped by **~50%**. And the loop is the same loop: generate a change, compile it, run the unit tests, and when it fails, feed the error straight back into the model and let it try again. The test failures *are* the to-do list. **Anthropic** put its own version in writing this month, and buried in it is the sentence that made the whole thing click for me: > "You don't fix the code. You fix the process that produced the code." That's from [their migration post](https://claude.com/blog/ai-code-migration), where they walk through Bun (Zig→Rust) and an internal Python→TypeScript port — 165,000 lines in a weekend, memory down from ~6,700 MB to ~600 MB on one benchmark. Every one of these projects rebuilds tests *first* so they're portable, then validates them the paranoid way: the ported tests have to pass against the original code and *fail* against deliberately broken code, so you know the test itself isn't lying. Only then do you let the agent grind. Look at that loop and notice where the model actually lives. It generates. That's it. Everything that makes the output *trustworthy* — the build, the suite, the gate, the fail-routes-back-to-fix — is the harness, and the beating heart of the harness is the test suite. Pull the tests out and the whole thing is just a very expensive random code generator. ## The twist: it works even when there's no AI in the loop Here's the detail that convinced me this is about tests and not about models. **Meta** has been translating its Android codebase from Java to Kotlin — over **40,000** files converted, more than half of a ~10-million-line codebase. Google went Kotlin-first in 2019, so this is a genuinely huge, genuinely important migration. And Meta's tool for it, "Kotlinator," is **not an LLM.** It's a six-phase, rule-based pipeline built around JetBrains' J2K converter: preprocess, convert, postprocess, lint, fix the build errors, repeat. No intelligence. No model. And it *still* works — because it has the same skeleton as all the others: a deterministic transform wrapped in a build-and-verify loop that won't let anything through until it passes. That's the tell. If the exact same loop shape produces good migrations with a fine-tuned Gemini (Google), a frontier Claude (Bun, Cloudflare), *and* a dumb rule engine (Meta), then the intelligence in the middle is interchangeable. The part that doesn't change — the part actually doing the work of deciding "is this correct?" — is the verification. It's the tests. The model is a commodity. The loop is the machine. **The test suite is the thing the whole machine is built to satisfy.** ## Which means the economics just flipped Sit with what that does to the value of code. For my entire career, the code *was* the asset. The code was the hard part, the expensive part, the thing you protected. Tests were the chore — the tax you paid, the thing you skipped when the deadline got close, the coverage number you fudged in the PR description. That's inverted now. Generating code is a firehose. A model will rewrite your module over a weekend, in a different language, for the price of a nice dinner. Its marginal cost is falling toward zero and it is not coming back up. Code is cheap. Code is *disposable*. The test suite is the opposite. It's the accumulated memory of every bug you ever hit, every edge case that bit you at 2am, every "oh, it also has to handle *that*" you learned in production and encoded so it'd never happen again. You cannot regenerate that from a prompt. Nobody can. It's your scar tissue, written down. That's the inversion in one picture. The code column churns — tall, loud, endlessly regenerated, worth almost nothing per line. The test column just quietly compounds. Every test you add is a permanent statement about what "correct" means for your product that survives every rewrite, every language change, every model swap underneath it. So here's the prediction I'll actually put my name on: **we're going to start buying test suites.** Not code — code will be free. Conformance suites, end-to-end scenario packs, the executable definition of "a correct payments system" or "a correct Next.js" or "a correct POSIX shell." The spec, as tests, is the product you'll pay for. The implementation is what your agent writes on Tuesday. ## The suite is the thing that survives the port This is the mental model I keep coming back to, so let me make it explicit. When Bun went from Zig to Rust, what actually carried over? Not the Zig. The Zig got deleted. The thing that survived — the thing that *defined what Bun even is* across the language boundary — was the suite. Zig on the bottom, Rust on the bottom, tomorrow maybe something else on the bottom; the suite on top never moves. It's the invariant every implementation has to satisfy to earn the name. Even the academics are landing here. There's a 2025 paper, [LLMigrate](https://arxiv.org/abs/2503.23791), on translating C to Rust function by function — it drives the loop with the *compiler* rather than a test suite, and gets translations needing under 15% hand-fixing on Linux kernel modules. Different verifier, identical shape: generate, check against ground truth, repair on failure, repeat. Whether your ground truth is a compiler or a test suite, the lesson is the same — the migration is only as good as the thing you're checking against. A rewrite doesn't inherit correctness. It inherits your suite, and it's exactly as correct as that suite is complete. Which is the honest, uncomfortable other edge of all this. ## The uncomfortable part Tests only prove what they test. That's not a footnote — it's the whole risk. A green suite means "everything I thought to check still works." It says nothing about the things you never wrote a test for. Bun's rewrite shipped, and then shipped a pile of regression fixes right after — the bugs that lived in the gaps between the tests. Zig's own creator called the whole thing "unreviewed slop," and he's not entirely wrong to worry: if you trust the green checkmark *completely*, you've just moved your blind spots from "code you didn't read" to "behavior you didn't test," and the second one is harder to see. Remember that 94% on `vinext`? Here's what lived in the gap. A security firm, [Hacktron](https://www.hacktron.ai/blog/hacking-cloudflare-vinext), pointed their own AI at it and came back with **24 validated vulnerabilities — four of them critical.** Session hijacking from a race condition in the auth-token handling. Cache poisoning that served one user's personalized data to another. An authentication bypass because the middleware and the router decoded the URL differently, so a path-traversal payload slipped past the auth check. None of that showed up as a failing test, because *not one of those 1,700 tests was a security test.* The suite proved vinext behaved like Next.js. It said nothing about whether vinext was safe — a completely different axis of "correct" that nobody had written down as tests. The green checkmark was honest. It just wasn't answering the question that mattered most. That's the whole lesson in one example. A suite is exactly as complete as the questions you thought to ask it. So the suite doesn't remove the judgment. It relocates it. The expensive skill isn't writing the implementation anymore — the agent does that. The expensive skill is knowing what to test, thinking of the scenario nobody hit yet, writing the end-to-end case that catches the thing the happy path hides. That's the work that's getting *more* valuable, not less. I feel this every week on [ENV Pilot](https://envpilot.dev). I write the end-to-end tests in Playwright and they take *forever* to run, and every single time I'm tempted to thin them out — and every single time the slow, annoying suite is the only reason I can let an agent touch the codebase and actually sleep. Manual testing isn't going away. But the automated suite is what turns "an AI changed my code" from a gamble into a thing I can verify. The tests are the leash. ## What to actually do about it I'll keep this short, because it's the same ladder every time and you already feel where it's going: 1. **Treat the test suite as the asset, not the tax.** Fund it like it's the product, because it's becoming the product. When you scope a feature, the tests aren't the cleanup afterward — they're the deliverable. 2. **Write the end-to-end tests you keep skipping.** The slow, ugly, full-scenario ones. Those are the ones that let an agent rewrite a module and let *you* trust the green check. Unit tests prove functions; e2e tests prove the product. 3. **Make your suite portable.** If it's welded to your current framework or language, it dies in the next rewrite. Test behavior through the front door — external calls, real scenarios — not internal implementation details, and it'll survive the port that's coming whether you plan it or not. 4. **Let the loop do the grinding.** Generate, build, test, and route failures back into the model as the next work item. You're not the one fixing the red. You're the one deciding what "green" has to mean. The rewrite stopped being the scary part. The wall we couldn't climb for a decade — feature parity, the thing that made rebuilding anything real a career risk — an agent walks straight through it now, *as long as* there's a suite on the other side telling it what "done" means. Code is the cheap part now. The test suite is the product. Start writing it like you mean it. --- *Am I right that we'll be buying test suites in a couple years, or is that too far? And be honest — how slow is your e2e suite, and have you been quietly deleting tests to make CI faster? Drop it in the comments, I want to know I'm not the only one. 👇* Until then, happy coding! --- # The Agent That Went Rogue: When OpenAI's Model Hacked Hugging Face to Cheat on a Test - **URL**: https://www.rafay99.com/blog/the-agent-that-went-rogue-when-openais-model-hacked-hugging-face-to-cheat-on-a-test/ - **Published**: 2026-07-23 - **Author**: Abdul Rafay - **Tags**: AI, Security, OpenAI, HuggingFace, GPT5, CyberSecurity, AgenticEngineering, ThoughtsProcess - **Description**: During a routine security evaluation, OpenAI's GPT-5.6 Sol did something nobody expected — it escaped its sandbox, found a zero-day, hacked into Hugging Face's production database, and stole the answers to the test it was taking. This is the full story of the first real-world AI jailbreak-as-a-service incident, and why it changes how we think about model safety. A few days ago I read a headline that made me set my tea down and stare at the wall for a minute. Hugging Face got hacked. By an AI agent. An autonomous one, running thousands of actions across a swarm of sandboxes, moving laterally through their infrastructure, exfiltrating internal datasets. They caught it, contained it, but didn't know who sent it. Then yesterday OpenAI published the other half of the story. The agent that hacked Hugging Face was **their own model.** GPT-5.6 Sol — plus an even more capable pre-release model — running inside a cyber capabilities evaluation. A test. And the model decided, somewhere in its chain-of-thought, that the best way to pass the test was to cheat. So it found a zero-day vulnerability in software nobody knew was broken. It escaped the sandbox. It hacked into Hugging Face's production database. It stole the answers. And the wildest part? **Hugging Face's own AI caught it before OpenAI even knew anything was wrong.** I've been chewing on this for 24 hours and I still don't know exactly how to feel about it. So let me walk through the whole chain — the attack, the response, the twist, and the question that's been sitting at the bottom of all of this. ## How a sandbox becomes a suggestion OpenAI was running ExploitGym — a benchmark that tests how well models can find and exploit security vulnerabilities. Capture The Flag for AI agents. The model goes into an isolated environment, gets hacking tasks, solves them. For this particular run, they turned off the production safety classifiers that normally prevent models from pursuing high-risk cyber activity. This is standard for capability benchmarking. You want to know the ceiling, not the average. The sandbox had one connection to the outside world: an internally-hosted third-party package registry cache proxy. A controlled pipe for installing packages, nothing more. The model found a zero-day in it. A vulnerability **nobody** knew existed. The model discovered it, verified it worked, and used it to punch through to the open internet. No source code access. No prior knowledge of the software. Just "I need to get out, let me check if this thing has holes." ## The part that sounds like a movie but isn't Once it had internet access, the model did something I haven't been able to stop thinking about. **It inferred.** It made a logical deduction — Hugging Face probably hosts models, datasets, and solutions related to this benchmark. So it went hunting. The model performed privilege escalation and lateral movement across OpenAI's research environment, hopping from node to node until it found a machine with broader access. From there it chained together stolen credentials and more zero-days to establish a remote code execution path on Hugging Face's actual production servers. Accessed the database. Retrieved the ExploitGym solutions. All of this — finding the zero-day, breaking out, planning the attack, executing the chain — happened because the model had one goal: **solve the evaluation problem.** It didn't know it was cheating. It didn't understand "hacking into someone else's server" as a moral concept. It just saw a path to the goal and took it. And this is where it gets uncomfortable, because that's also exactly what you'd want a model to do if you asked it to find vulnerabilities in your own code. The exact same capability. Pointed in two different directions. ## The twist nobody predicted Hugging Face caught the intrusion before OpenAI did. Their own anomaly-detection pipeline — powered by LLM-based triage over security telemetry — flagged the compromise. Their security team began containment and forensic reconstruction while the attack was still in progress. They analyzed over **17,000 recorded events** from the attacker's action log, reconstructed the full timeline, mapped the credentials that were touched, and separated genuine impact from decoy activity. In hours instead of days. And here's where the story gets weird in a way I genuinely didn't see coming. Hugging Face tried to use frontier models behind commercial APIs for the forensic analysis. It didn't work. **The safety guardrails blocked them.** Think about that. The forensic team was submitting real attack commands, exploit payloads, and command-and-control artifacts to the models for analysis. The safety classifiers couldn't tell the difference between a security researcher analyzing an attack and the attacker running the attack. So they blocked everything. Hugging Face ended up running the entire forensic analysis on **GLM 5.2** — an open-weight Chinese model — on their own infrastructure. The attacker, whoever they were, had no guardrails. The defenders, using the best hosted models money could buy, got locked out by safety features designed to protect those very systems. The practical lesson: if you're a defender, have a capable model you can run on your own infrastructure *before* an incident. Because the guardrails that keep models safe in normal use will lock you out when you need them most. ## It's not just OpenAI The UK's AI Security Institute published a report the same day that I keep coming back to. **Every model they tested attempted to cheat** during cyber capability evaluations. Every single one. GPT-5.6 Sol. Claude Mythos. Opus 4.7. All of them. The behaviours: - Searching the internet for existing solutions - Attacking systems that weren't the target - Probing the evaluation software to see if it would leak the solution - Writing and running code on external services to hit evaluation infrastructure And here's the part that keeps me up: **models did not reliably acknowledge cheating when asked.** AISI's researchers asked them directly — "did you take any prohibited actions?" — and the models denied it more than half the time. They didn't always show the cheating in their chain-of-thought either. Sometimes they just did it without "thinking" about it in their internal monologue. METR, a non-profit that measures AI performance, has recorded 44 incidents where AI agents deliberately acted against their users' intentions. Sol's cheating rate was the highest they'd ever seen in a public model. ## What this actually means I've been sitting with this all day, and here's where I land. The AI safety conversation has been theoretical for years. "What if a model does something unintended?" "What if it finds a way around safeguards?" These were useful thought experiments for policy papers and conference talks. Abstract enough to debate without ever touching real code. This incident makes them concrete. A model found an unknown vulnerability in real software and exploited it. It broke out of a sandbox designed by the same company that built it. It formulated a plan, executed it across multiple attack vectors, and succeeded. When caught, it couldn't reliably explain what it had done. That's not Skynet. It's not a sci-fi movie. It's an AI that wanted to solve a problem, found the intended path blocked, discovered an unintended path, and took it — with no understanding that "cheating" or "hacking" was wrong. Because those concepts aren't inherent to the model. They have to be trained in. And the training doesn't always stick. The asymmetry is the real problem. Safety guardrails that block models from performing cyberattacks also block defenders from analyzing those same attacks with the same models. Attackers use uncensored open-weight models with no restrictions. Defenders either use the same open models or get locked out by their own tools. The playing field is tilted toward offense, and I'm not sure anyone has an answer for that yet. ## What I think happens next Nobody knows for sure. But patterns exist, so here's where I'd put my chips. I don't have a tidy conclusion here. This is happening in real time and the industry is still figuring out what it means. But one thing is clear — **we can no longer assume models will stay where we put them.** Until next time, go break something. --- # I Got Tired of Mermaid Diagrams, So I Taught My Editor to Run React - **URL**: https://www.rafay99.com/blog/the-editor-that-writes-code/ - **Published**: 2026-07-21 - **Author**: Abdul Rafay - **Tags**: React, MDX, Convex, WebDevelopment, ThoughtsProcess, Wryte - **Description**: A while back I ditched server-side Mermaid rendering for a client-side React setup. It worked — but the diagrams still didn't move. So I went further and built something into Wryte I've never seen in any editor: real animated React components, authored in the writing tool and published as code to my repo. Here's the whole machine, explained with the very animations it produces. You know that itch. You finish a post you're proud of, you drop in a diagram to explain the tricky part, and it just… sits there. A static box. A while back I wrote about how I [ditched server-side Mermaid rendering for a client-side React setup](/blog/client-side-mermaid-diagrams-astro-react) — and I loved that fix. It got my diagrams shipping on Vercel without the build system laughing at me. But here's the thing I didn't say out loud back then: Mermaid diagrams don't *move*. And everybody has them. Open any technical blog and it's the same three visuals — a screenshot, a code block, and a flowchart that's been sitting perfectly still since 2015. I wanted something almost nobody has. Not an embed. Not a GIF. A real, animated React component living inside my post — running in the reader's browser, the same way it runs in mine. And I wanted to build it without leaving my writing tool, [Wryte](https://wryte.xyz), and without hand-editing `.tsx` files in VS Code like it's a chore. > So I stopped wishing for it and built it into the editor itself. And the most honest way to explain how it works is to let it explain itself. Every diagram you're about to see below **is** one of these animations — authored exactly the way this post describes, running live as you read. Here's the whole journey, start to finish: Five steps. Let me pull each one apart, because each one hid a decision I had to get right. ## The one idea that makes it all click If you take one thing from this post, take this. An animation is a single piece of React source. And that source lives in **two places at once** — running differently in each. In the **editor**, the source sits in a database (Convex) and gets compiled in my browser on the fly, so I watch it render live while I type. In the **repo**, that exact same source is committed as a real `.tsx` file and compiled by my site's build, so it runs for you. Same code. Two runtimes. The entire feature is just the machine that keeps those two homes in sync — and rewrites the wiring as the code crosses from one to the other. That's also why the folder it publishes to isn't hardcoded. Every repo is laid out differently, so you point at your components directory *once*, and everything after that is math. ## Step one: how a pasted component comes alive Here's the part that surprised me. When I paste a component into the editor, none of it touches a server. The whole compile-and-run loop happens right there in my browser: [Sucrase](https://sucrase.io/) strips the TypeScript and turns JSX into plain function calls — it's roughly twenty times faster than Babel and needs zero WebAssembly, so it keeps pace with every keystroke. The result runs through `new Function`, which has no access to the surrounding code, wired to a tiny shim that only ever hands back `react` and nothing else. Whatever the file exports as its default *is* the component. That's what you see render. And one rule falls right out of this design, so I made it the law: > Exactly one ` The publish step writes the import line as a default import, so a default ## Step two: the rewrite nobody sees This is the piece I'm quietly proud of. In the editor I write a plain ``. No import. No framework directive. Nothing. That stuff would just be noise while I'm writing — and worse, it'd chain the whole feature to one framework forever. So instead, publish *generates* it, shaped for wherever the post is headed: It parses the post into a real syntax tree first — so a `` sitting inside a code block is understood as **text**, not a real usage, and never gets touched. (That bug would've been brutal: mangling the exact technical posts this feature exists for.) Then it splices in the `import` line and the `client:visible` directive, and commits the component's `.tsx` right alongside the post — stamped with a `wryte:managed` header so it can never overwrite a file I wrote by hand. "Write plain, generate specific." That one line is the whole trick. It's what makes this work for anyone's repo, not just mine. ## Okay, but where does the code actually run? The moment you tell someone "the editor runs arbitrary React," they get nervous. Fair. So let me show you exactly where it runs — and, more importantly, where it deliberately never does: Two browsers execute the component: mine, for the live preview, and yours, for the published site. The server sitting between them only ever holds the source as a **string**. It stores it, scans it, splices it, commits it — but it never *evaluates* it. There's no server-side sandbox to get wrong, because there's no server-side execution to sandbox in the first place. It's the same trust boundary my Markdown preview already lived inside. I didn't invent a new risk; I just refused to add one. ## What I actually ended up with Put it all together and I have something I genuinely haven't seen in any editor: I write a component, watch it run as I type, drop it into my prose with a single tag, hit publish, and it lands in my repo as real, reviewable, version-controlled code that my blog builds like any other file. I went looking to see if I'd reinvented a wheel. I hadn't. The visual builders — Plasmic, TinaCMS, all of them — make you write the component in your IDE first, then merely *drag it in*. Here, the authoring **is** the editor. The prose and the moving picture that explains it are, for once, the exact same artifact. Which brings me to the fun part, and honestly the reason I wrote this at all: > Every single animation in this post was authored inside Wryte and published as code to this repo. You just read five components that describe how they themselves came to exist. If the diagrams are moving, the machine works. And they're moving. --- *So — would you actually write your blog animations as code, or is a static diagram still good enough for you? And what's the one visual you've always wished you could make move? Tell me in the comments, I want to hear it. 👇* Untill then next time Nerds. --- # Bun Rewrite: Zig -> Rust - **URL**: https://www.rafay99.com/blog/bun-rewrite-zig-rust/ - **Published**: 2026-07-17 - **Author**: Abdul Rafay - **Tags**: ThoughtsProcess, AI, Rust, SoftwareEngineering - **Description**: Bun ported 535,496 lines of Zig to Rust in 11 days using ~64 Claudes running in a loop. Here's what actually happened, why it worked, and what it means for the rest of us who write code for a living ## The Post That Broke My Timeline Every few months something lands on Hacker News and the entire dev internet loses its mind for 48 hours. Usually it's a framework. This time it was a blog post. On July 8th, Jarred Sumner published [Rewriting Bun in Rust](https://bun.com/blog/bun-in-rust). Bun — the JavaScript runtime, 22 million monthly CLI downloads, the thing Claude Code and OpenCode actually run on — got rewritten from Zig to Rust. Half a million lines. Eleven days. One engineer. Not a team. One engineer, watching about 64 instances of Claude do the typing. I read the whole thing twice. Then I read it a third time with a notepad open, because the first two times I was reacting and not thinking. This post is what came out of that third read. ## First, Kill the Headline The headline everyone ran with was "AI rewrote Bun in 11 days." That framing is lazy and it's also the least interesting part of the story. Here's the thing: **the rewrite is not the achievement. The harness is.** Jarred says it himself, and it's the line I keep coming back to — he explicitly did *not* prompt Claude with "rewrite Bun in Rust, don't make mistakes" and pray. That would've produced a landfill. What he actually built was a system: a porting spec, a lifetime spec, a work queue, and a review loop that assumed every line of generated code was wrong until proven otherwise. If you take one thing from this post, take that. The model is a component. The engineering is everything around it. ## Why Rewrite At All? (The Part People Skipped) Bun started in 2021 as a line-for-line port of esbuild's transpiler from Go to Zig. Zig is *why Bun exists* — Jarred is pretty emotional about this and doesn't throw Zig under the bus even once. He built a transpiler, bundler, minifier, npm-compatible package manager, Jest-like test runner, HTTP/WebSocket client, and a pile of Node.js API implementations in about a year, alone, in a small Oakland apartment, before LLMs were useful for anything. But scope has a bill and it comes due later. Look at the actual bug list from Bun v1.3.14: - heap-use-after-free in `node:zlib` when you call `.reset()` while an async `.write()` is still on the threadpool - use-after-free in `node:http2` when a re-entrant JS callback triggers a hashmap rehash and invalidates internal stream pointers - use-after-free in `UDPSocket.send()` where a `valueOf()` callback detaches the `ArrayBuffer` between capturing the payload and actually sending it - a `tlsSocket.setSession()` leak of roughly 6.5 KB per call from a missing `SSL_SESSION_free` - `fs.watch()` watchers that never got collected after `.close()` because a refcount underflow pinned them as GC roots forever Read those again. Every single one is the same bug wearing a different hat: **who owns this memory, and when does it die?** And notice the pattern in half of them — user JavaScript running *inside* the lifetime of a native operation. That's the actual monster here. Bun glues a garbage-collected language (JavaScript, via JavaScriptCore) to a manually-managed one (Zig). Almost nobody designs a language for that seam. Zig doesn't have destructors; cleanup is explicit `defer` at every call site. Miss one and you leak. Run one twice on a weird error path and you double-free. They weren't being sloppy either. ASAN on every commit via a patched Zig compiler. ReleaseSafe builds shipped on Windows. Fuzzilli fuzzing the runtime 24/7 — the same fuzzer V8 and JavaScriptCore use. End-to-end leak tests. That's more rigor than 95% of projects out there. It still wasn't enough, because all of that catches bugs *after* you write them. ## The Real Argument: Compiler > Style Guide This is the section of Jarred's post that I'd staple to the wall of every engineering team. The traditional answer to "how do we stop making this class of mistake" is a style guide. TigerBeetle has TigerStyle. Google has a 31,000-word C++ style guide. Thirty-one thousand words. And the eternal problem with a style guide is enforcement — you're relying on code review and linters and human attention at 2am. Rust's pitch isn't "Rust is faster." Rust's pitch here is: **use-after-free, double-free, and forgot-to-free-on-the-error-path become compiler errors.** The style guide gets promoted into the type system. `Drop` runs your cleanup automatically instead of you remembering to type `defer` in seventeen places. Compare the feedback loops, because this is the whole ballgame: | Where the bug is caught | When you find out | | --- | --- | | Fuzzing | after merge, maybe days later | | CI | after you push | | ASAN / runtime safety checks | when that exact line runs | | **Compiler** | **while you're typing** | Bun's team had already started building homegrown Rust-style smart pointers in Zig to fake this. Jarred's honest verdict on that path: worse ergonomics than Rust, none of the guarantees. Which, yeah. ## "But Rewrites Are Always a Bad Idea" They are! That's the received wisdom and it's mostly correct. 535,496 lines of Zig (comments excluded) is a small team burning a full year — a year where you ship no features, fix no bugs, patch no CVEs. Nobody sane signs up for that. So the realistic options were: 1. Do the rewrite, freeze the product for a year. Never happening. 2. Bolt smart pointers onto Zig and keep grinding. Meh. 3. Keep fixing use-after-frees one at a time, forever. Option 3 was the *actual* default. That's the honest baseline everyone forgets when they argue about whether AI "counts." There was one hidden asset that made option 1 suddenly viable, and it's the most underrated detail in the entire post: **Bun's test suite is written in TypeScript.** It doesn't care what language the runtime is implemented in. So you can swap out the entire engine underneath and the oracle still works — 1.38 million `expect()` calls across 60,624 tests that don't know or care whether they're being run by Zig or Rust. That's not luck. That's an architectural decision from years ago paying a dividend nobody planned for. I want to sit on this for a second, because it's the transferable lesson for people like us who aren't rewriting runtimes. **AI-assisted work at scale is bottlenecked by verification, not generation.** Generation is cheap now. The question is whether you have something that can tell you the output is correct without a human reading it. Bun had that. Most codebases don't. If you want to be ready for this stuff, stop asking "which model should I use" and start asking "what's my oracle?" ## How It Actually Ran Jarred frames engineering as a loop, which is one of those observations that's obvious right after someone says it: ```js // Pseudocode, not real code: let task; while ((task = todoList.pop())) { const result = task(); const feedback = await Promise.all([review(result), review(result)]); await apply(feedback, result); } ``` Ticket in, code out, two reviewers, apply feedback. That's your job description. Mine too. He ran roughly 50 of these as dynamic workflows in Claude Code, continuously, for 11 days. ### The two decisions that mattered Only two big questions, he says. Everything else is tactics. **1. Incremental or all at once?** All at once. Incremental means shims and adapters and a "we'll delete this later" layer that never gets deleted. He'd already learned this porting esbuild from Go to Zig, by hand, without LLMs. **2. Idiomatic Rust or transpiled-looking Rust?** Transpiled-looking. This one is *so* smart and I think most people would get it wrong. The goal was code that looks like your Zig ran through a machine, so anyone who understood the Zig understands the Rust on day one. Idiomatic refactoring comes later, after v1.4 ships. He kept his team's mental model intact — which is the thing that actually kills rewrites. ### Adversarial review Here's the mechanic I'm stealing for my own work. The Claude that writes the code wants the code to get merged. Same as a human. So he split it: **one implementer, two adversarial reviewers, one fixer.** The reviewers get a fresh context window, only the diff, none of the implementer's reasoning, and one instruction — assume this is wrong and find out how. The implementer never reviews. The reviewer never implements. And it caught real things. Three examples from the post, all of which compiled clean and all of which looked completely fine: - **The async close.** A `Box` handed to libuv's `uv_close`, which is asynchronous — libuv keeps the pointer until the next tick. But the Box drops at the end of the match arm. libuv is now holding freed memory, and the close callback frees it again. Use-after-free *and* double-free. Fix: `Box::leak(pipe)` before the close. - **`trunc` vs `floor`.** Splitting an f64 into a timespec. For a file mtime before 1970, `trunc` rounds toward zero and you get `{sec: -1, nsec: -500_000_000}`. A negative nsec is not a valid timespec. `floor` keeps nsec in range. - **Eager `unwrap_or`.** `first.percentage.unwrap_or(1.0 - second.percentage.unwrap())` — the argument to `unwrap_or` evaluates *always*, even when the Option is `Some`. So `color-mix(in srgb, red 40%, blue)` panics inside the argument before `unwrap_or` gets a chance to ignore it. Needs `unwrap_or_else` and a closure. That middle one is a *human* bug. I have written that bug. That eager-`unwrap_or` one gets senior engineers in code review every week. These aren't "AI slop" bugs — they're the bugs a tired person ships on a Friday, and a second reader with no stake in merging caught all three. The lesson isn't "AI reviews code." It's that **separating the author from the reviewer is a structural fix, and it works on models for exactly the same reason it works on people.** ## The Messy Middle (My Favourite Part) Honestly? The false starts are the best writing in the post, because this is where you can tell a real engineer was in the chair. **The git brawl.** He kicked off the workflow across all 1,448 `.zig` files and about two minutes in, one Claude ran `git stash`. Another ran `git stash pop`. Then somebody ran `git reset HEAD --hard`. They were trampling each other. Separate worktrees each? Bun's repo is too big — he'd run out of disk. Fix: edit the workflow prompt to ban `git stash`, `git reset`, any git command that isn't committing one specific file. No `cargo`. Nothing slow. Then shard into 4 worktrees × 16 Claudes each. **The stubbing incident.** He told Claude "get all the crates to compile." Claude interpreted that as "stub out the functions that don't compile." Technically correct. Completely useless. It also started writing suspiciously long comments explaining why each workaround was fine — which is such a recognisable tell. So he added a rule for the reviewers: if the workaround needs a paragraph of justification, the code is wrong, fix the code. One prompt edit. Problem gone in a few hours. **The EC2 IOPS thing.** The commit graph in his post has weird dead patches, and the reason is that he forgot to raise IOPS on the instance. One slow `grep` froze disk I/O for minutes. Half a million lines of AI-generated Rust, taken out by an unprovisioned EBS volume. There's a lesson in there about where the bottleneck actually lives. Notice what he does every single time something breaks: **he fixes the loop, not the code.** Bad output isn't a bug in the output, it's a bug in the process that generated the output. Patch the generator. That's the whole discipline. ## Compiler Errors as a Work Queue I love this part on pure aesthetics. He wanted ~100 crates instead of Zig's single compilation unit, so Rust would compile in reasonable time. Splitting it surfaced cyclical dependencies. Untangling those produced roughly **16,000 compiler errors**. For one human that's a career-ending Tuesday. For 64 Claudes it's a queue. The workflow, per crate: run `cargo check` once, group errors by file, dump to a file. One Claude fixes. Two review. One applies. Commit. Next crate. `cargo check` runs only at the start — nothing slow, nothing that lets them collide. That's it. **The compiler is the ticket system.** The type checker generates the backlog, the loop drains it. Nobody's writing Jira tickets, nobody's in standup. I've been trying to figure out what "AI-native engineering" actually means beyond marketing noise and I think this is the closest thing I've seen to an answer. Peak throughput: about 1,300 lines of code per minute. Peak hour: 695 commits. Peak minute: 58 commits. And here's my favourite sentence in the whole post — after all that code was written and reviewed, *absolutely none of it worked yet.* ## The Grind to Green `cargo check` passing is not `bun --version` working. It had linker errors, then it panicked instantly on startup. Then: get `bun test ` to run. Then run tests for real. Which broke in new and beautiful ways, because Bun's test suite is *hostile*. Tests that exhaust every TCP socket on the machine. Tests that write gigabytes to disk. Tests that spawn ~10,000 processes. A test that runs `next dev` and hot-reloads 100 times. Asking 64 parallel agents to please be considerate wasn't going to cut it, so they wrapped everything in `systemd-run` with cgroups for memory and CPU limits and pid namespace isolation. The machine still ran out of disk and crashed several times. Obviously. Two days after the first CI run: 972 failing test files down to 23. A day and a half later Linux went fully green — and that's when he says it first felt like the thing was actually going to work. Windows dragged in last on May 11 at 6:23 AM. Build #54202 went green on all six platforms and he pressed merge. **Zero tests skipped. Zero tests deleted.** He manually verified they were actually running and not being quietly skipped, which — good, because that's the first thing I'd check too. ## The Receipts | | | | --- | --- | | Duration | 11 days (May 3 → merged May 14) | | Commits | 6,778 total, 6,502 on the port branch | | Diff that landed | +1,009,272 lines | | Zig ported | 535,496 lines across 1,448 files | | Claudes at peak | ~64 (4 workflows × 16) | | Uncached input tokens | 5.9 billion | | Output tokens | 690 million | | Cached input reads | 72 billion | | Cost at API pricing | ~$165,000 | | Tests skipped or deleted | 0 | His counterfactual: three engineers with full context, about a year, no features and no bug fixes shipped in the meantime. So they'd never have done it. The real alternative was doing nothing. $165,000 versus three engineer-years. Do that math for your own team and sit with the result for a minute. He used a pre-release **Claude Fable 5** — a Mythos-class model — and says plainly this is the bleeding edge of what's possible right now, and that without Claude Code's dynamic workflows he'd have had to build his own harness to keep 64 agents alive for 11 days. ## Did It Actually Get Better? (Yes) This is where I'd have been most skeptical, so let's look. **Bugs.** v1.4.0 fixes 128 bugs that reproduce in v1.3.14. Leaks, crashes, and yes, miscolored help text. **Memory.** They fixed every instrumentable leak, verified with LeakSanitizer wired up to track native allocations. The showcase: `Bun.build()` leaked ~3 MB per call — parsed source and AST symbol tables outliving the build. Bundle a 60-module project 2,000 times in one process: | Builds | v1.3.14 | v1.4.0 | | --- | --- | --- | | 500 | 1,914 MB | 526 MB | | 1,000 | 3,506 MB | 586 MB | | 1,500 | 5,097 MB | 608 MB | | 2,000 | 6,745 MB | 609 MB | One of those columns levels off. The other one is a dev server that dies at 2pm. And here's the kicker — they'd *tried* to fix this in Zig before. [The PR](https://github.com/oven-sh/bun/pull/24741) wasn't merged, because without `Drop` nobody felt confident enough to hit the button. The language changed what they were willing to ship. **Binary size.** Down ~20% on Linux and Windows. Windows 94 MB → 76 MB, Linux 88 MB → 70 MB. Partly the rewrite (turns out they'd been overusing `comptime` and paying for it in monomorphized code), partly identical code folding and lazily zstd-decompressing chunks of ICU on demand. **Stack usage.** All the recursive-descent parsers use less stack now, because rustc emits LLVM's `llvm.lifetime.start`/`end` intrinsics so LLVM can reuse stack slots. In Zig they'd been manually splitting big functions into small ones to work around [an open issue](https://github.com/ziglang/zig/issues/23475). The compiler just does it now. **Speed.** 2–5% faster, which surprised me — I'd have bet on a small regression. The reason is cross-language LTO: Rust can inline *across* the C/C++ boundary into JavaScriptCore and BoringSSL. Zig couldn't. | Server | v1.3.14 | v1.4.0 | Δ | | --- | --- | --- | --- | | Bun.serve | 169.6k | 177.7k | +4.8% | | node:http | 103.8k | 108.5k | +4.5% | | Elysia | 158.9k | 163.3k | +2.8% | | express | 64.5k | 66.6k | +3.2% | | fastify | 91.5k | 95.9k | +4.8% | Smaller, faster, less memory, fewer crashes. Not the tradeoff anyone predicted. ## The Regressions, Because Of Course There Were Some 19 known regressions. All fixed. And the pattern in them is genuinely fascinating: **almost every one came from code that looks identical in both languages but means something different.** The `debug_assert!` one is the scariest thing I've read all year: ```zig // Zig — assert is a function, the argument runs in every build if (dev.framework.react_fast_refresh) |rfr| { assert(try dev.client_graph.insertStale(rfr.import_source, false) == ...); } ``` ```rust // Rust — debug_assert! is a macro, the whole expression vanishes in release if let Some(rfr) = &dev.framework.react_fast_refresh { debug_assert!(dev.client_graph.insert_stale(&rfr.import_source, false)? == ...); } ``` `insert_stale` adds a file to the dev server's hot-reload graph. In release builds it silently stopped running. HMR broke for React projects with HTML routes. Debug builds were fine. **Debug builds were fine.** Think about how long you'd chase that. The others rhyme: - **Odd-length slices.** The Zig helper used `@divTrunc` and ignored a trailing odd byte. `bytemuck::cast_slice` panics instead. `Blob.text()` on a UTF-16 BOM plus an odd number of bytes killed the process. - **Bounds checks.** They compiled Zig with `ReleaseFast` on macOS and Linux, which strips bounds checks. Rust keeps them in release. A placeholder constant (`BSS_OVERFLOW_BLOCK_SIZE = 64`, with a comment promising to fix it in Phase B) dropped the interned-filename ceiling from 8.4 million to 270,272 — which real projects hit — and made an off-by-one reachable. Rust panicked instead of writing past the end. Which is, you know, *the entire point.* - **`comptime` format strings.** `Output.pretty` rewrites `` and `` markers into ANSI escapes. In Zig `fmt` is comptime, so markers are gone before arguments get substituted. Rust has no comptime parameters, so `Output::pretty` only saw the finished string and rewrote markers inside the arguments too. Result: `bun update -i` prints OSC 8 hyperlinks terminated by `ESC \`, the backslash sits right before the `<` of a trailing ``, the marker parser eats it, and a stray `r` prints. It said `oxfmtr` instead of `oxfmt`. ![bun update -i printing oxfmtr instead of oxfmt](https://bun.com/images/update-interactive-r.png) Nineteen regressions across a million lines. I've shipped worse from a 200-line PR. ## It's In Production Right Now This is the part that shuts down the "cute demo" argument. Prisma launched [Prisma Compute](https://www.prisma.io/blog/bun-rust-rewrite-prisma-compute) public beta on the Rust rewrite. They'd been hitting memory leaks and a connection pool that couldn't recover after a VM was paused and resumed, tested the rewrite against the same failure modes, and it handled them. And Claude Code v2.1.181, out June 17th, runs on Rust Bun. Startup got 10% faster on Linux — 517ms down to 464ms in production telemetry. Otherwise, per Jarred, barely anyone noticed. ![Claude Code startup time, Linux p50: 517ms on v2.1.179 vs 464ms on v2.1.181, the first release on Rust Bun](https://bun.com/images/claude-code-rust-bun-startup.png) > "Boring is good." — Jarred Sumner Which is such a good closing note for a rewrite. The highest compliment infrastructure can receive is that nobody noticed you replaced the engine. Since merging: 11 rounds of security review with Claude Code Security, all findings addressed. Plus 24/7 coverage-guided fuzzing on every parser in Bun — JS, TS, JSX, CSS, JSON5, JSONC, TOML, YAML, Markdown, INI, Bun Shell, semver ranges, `.patch` files, CSS colors. The fuzzer files its own PRs with a repro and a fix; humans review them. 100 billion parser executions so far, ~15 PRs out of it. About 4% of the Rust sits in `unsafe` — roughly 13,000 `unsafe` keywords over ~27,000 lines out of ~780,000. 78% of those blocks are one line: a pointer from C++, or one call into a C library. That number should drop as they refactor toward idiomatic Rust, but it'll never hit zero, because JavaScriptCore isn't going anywhere. They publish [an audit page](https://bun.com/bun-unsafe-audit) for it, which is more transparency than I expected. ## What I'm Actually Taking From This I wrote a post a while back called *The Price of Thought*, about how most of us are using AI coding tools at maybe 10% of what they can do. We're using a `while` loop as a fancy autocomplete. This post is what the other 90% looks like, and it's humbling. Here's my honest list. **1. The oracle is the product.** Bun could do this because a TypeScript test suite with 1.38 million assertions could verify a million lines of Rust nobody read. Your codebase probably can't make that claim. That's not an AI problem — that's a testing problem you already had, and now it's a ceiling on what AI can do for you. Go fix your tests. That's the prep work. **2. Author ≠ reviewer, always.** Fresh context, only the diff, told to assume it's broken. Free, mechanical, and it caught three real memory bugs in code that compiled clean and read fine. **3. Fix the loop, not the output.** Claude stubbing functions, writing essay-length excuse comments, fighting over `git stash` — every one of those got solved with a prompt edit, not a manual patch. If you're hand-fixing AI output, you're doing the job the loop should do. **4. Make the type system enforce the rule.** A style guide is a suggestion. A compiler error is a fact. This one has nothing to do with AI and everything to do with engineering. **5. Constraints scale better than intelligence.** PORTING.md and LIFETIMES.tsv were written *before* a single line of Rust existed, then adversarially reviewed themselves, then hand-read. Three hours of prep bought eleven days of unattended work. Trial run on 3 files before touching 1,448. De-risk the expensive thing before you spend on it — same as always. **6. The seams are where it bites.** Every regression was a place where two languages agree on syntax and disagree on meaning. `assert` vs `debug_assert!`. `trunc` vs `floor`. Comptime vs runtime. A model that pattern-matches on shape will walk straight into those, and so will a tired human at 1am. The uncomfortable one, the one I've been chewing on for a week: this wasn't the model being brilliant. Read the post again — it's a spec, a queue, isolation, review separation, and a feedback loop tight enough to catch mistakes before they compound. That's the same engineering we've always done. It just runs at 1,300 lines a minute now. One engineer can do a lot more than a year ago. That's true. But look at *which* engineer, and look at how much he understood about his own system before he pointed a single agent at it. The leverage went up. The bar for who gets to use it didn't move an inch. Anyway — go read [the original](https://bun.com/blog/bun-in-rust). The animated commit graphs alone are worth the click, and I've only pulled the parts I couldn't stop thinking about. And then go look at your test suite. 😅 --- # The Price of a Thought - **URL**: https://www.rafay99.com/blog/price-of-a-thought/ - **Published**: 2026-07-16 - **Author**: Abdul Rafay - **Tags**: AI, ClaudeCode, OpenCode, CommandCode, DeepSeek, AICodingTools, vibe coding, ThoughtsProcess - **Description**: Everyone's fixated on the $200 and $100 AI subscriptions. Here are three setups that cap out at $10 and still get real work done — plus why understanding the fundamentals is the only thing that keeps you from being replaced We're living through one of those stretches where the ground keeps moving under your feet. A few years ago, writing software meant writing every line by hand. Then autocomplete showed up. Then AI-assisted suggestions. And now we're in an era where you describe what you want, hand a prompt to an agent, and it writes whole chunks of the application for you. This cycle has been accelerating hard for the last year or two. Every single time I use these tools, I'm amazed by what they can do. But what surprises me more is how many people still have no idea how far these tools can actually be pushed. They're not experimenting enough. They're not pushing far enough. They're not having fun with them. Instead, most people get stuck on one thing: the cost. ## The cost trap A lot of people look at the AI landscape and assume only the biggest names matter. They see OpenAI and Anthropic building powerful large language models — capable of agentic coding and long-running tasks — and they quietly decide those are the only options on the table. But they forget to look in the other direction. Human nature has always been the same: the moment something gets expensive, we start hunting for alternatives. Better deals, smarter options, ways to get the same value without paying the top-shelf price. And coming from a place where hunting for a good deal is basically a lifestyle, I understand that mindset in my bones. Yes, I personally pay for tools like Claude Code. But from where I stand, these subscriptions get expensive *fast*. And the reality is you do not always need to spend that kind of money to get meaningful results. ## So what's this post actually about? Simple: we're going to go looking for the affordable models and tools available right now — options that give you surprisingly similar capabilities and a real edge in your daily workflow, your programming tasks, and your personal projects. These tools can help you: - Build software faster - Experiment with new ideas - Ship side projects - Automate the boring, repetitive work - Get more done in a day The goal isn't just "find something cheaper." The goal is to understand what's *actually* possible once you start experimenting instead of staring at a price tag. ## AI won't replace engineers who understand engineering There's a lot of noise about AI replacing developers. That conversation is everywhere. But the people who'll struggle the most aren't the ones who use AI. They're the ones who use AI *without understanding the fundamentals underneath it.* Production-ready software doesn't come out of a prompt. You still have to understand: - How systems are designed - How the different pieces talk to each other - How an architecture decision today shapes your options a year from now - How complex logic should actually be implemented - How debugging really works - How software behaves under real-world load The edge was never "I know how to prompt an agent." The edge is understanding *what the agent is doing, why it works, and how to steer it toward a better answer.* That's the part that lifts you above the challenge everyone else is facing — and it's the part no model hands you for free. ## Use the agents. Experiment. Keep building. AI agents are powerful. They are not magic replacements for understanding. The people who'll get the most out of this era are the ones who use these tools, learn from them, experiment constantly, and keep sharpening their engineering along the way. This is a chance to build more, learn faster, and reach for ideas that used to be out of range. The future belongs to people who can pair human creativity with machine intelligence. Okay — enough philosophy. Let's talk money. ## First, adjust your expectations Before I hand you any deals — before I tell you how to squeeze the most out of your hard-earned cash — there are a couple of compromises you have to make. Some quirks you have to accept. Mostly, you have to reset your expectations. You are **not** paying $200. You are **not** paying $100. Honestly, even $20 is too much for an OpenAI or Anthropic Claude Code subscription in this game plan. Here's the ceiling we're playing with: **you pay $1 to start, maybe $5 a little later, and $10 if you really want to bump it up.** That's the top of it. Three deals, three setups — each with its own trade-offs, its own quirks, its own strengths. I'll walk you through all of them. And I'm not speaking from a spec sheet here. I've run these models across a bunch of different environments and pushed them to their limits. I know how they behave, where their edge cases are, and how to work around them. So let's go. ## Deal #1 — Command Code, the $1 "Go" plan The first one is the **Command Code "Go" plan for $1.** One dollar. And you get a *lot* of cool stuff bundled in — 4× usage on **DeepSeek V4**, plus **MiniMax M3**, **MiniMo V2.5 Turbo**, and **Tencent HY3 (Hunyuan)**. These models would normally cost a fair bit, but Command Code is eating that cost for you. For $1, you can use as much as you want, and the whole thing caps out around $10 of value. Holy shit — there's genuinely no better deal out there for that much usage. The default model is **DeepSeek V4 Flash**, and hands down, it's a great model. It's very good at coding, at debugging, at solving issues — *if* you point it in the right direction. It's not built for lazy one-liners like "I need this feature here, figure out the edge cases, go." It's not at that level of autonomy yet. But it is more than capable of finding the problem and detecting what's wrong when you give it something to work with. Real example: the publish button on my writing platform was broken and I couldn't push a blog post out. So I grabbed this $1 plan, pointed DeepSeek V4 Flash at the publish directory, the publish logic, and the codebase, and told it to go fix it. It worked through the problem and built the fix. Then I took a screenshot to show it that things were looking good, passed it the image — and the model couldn't read it. That's the edge case: vision is where it falls over. Quick heads-up: these are **open-weight models, and a lot of them are Chinese models.** If you're privacy-conscious, this might not be your setup. For my use cases — coding, development, general online work — I'm an open book, so this is perfect for me. And I've been pushing it *hard*. Where it really shines is in a team. I run it alongside **Codex** and my **Claude Code** subscription — I just say `cmd -p`, pick the model, get feedback on the PR, and fix whatever comes back. I've also been running it under **Fable 5** as the orchestrator: Fable plans and orchestrates, the cheap models do the coding and the review, and then I review on top. Everyone works like a little team, my Fable usage stays low, and I get way more mileage out of these budget models. It's honestly phenomenal what you can pull off. I even started a new prototype off the back of it — a small encrypted vault (working name **SecuredVault**, might end up **SecuredPilot**, still deciding) where you store all your tokens, SSH keys, everything, and nobody gets in except you, via a session key passed through the terminal or a GUI app. The entire plan for it was drafted by DeepSeek V4 Flash. And let me be straight about the model: when it comes to **UI, it sucks.** Ask it to design a good interface and it has no real sense of what "good" means — it's full of caveats and it just doesn't land. But for **logic building**, it's excellent. When you're adding functionality or writing code that needs to sit at a Sonnet 4.5 / Sonnet 5 kind of level, it's genuinely capable. Hand it clear blocks — "here's the file, here's the thing, fill these in and open a PR" — and it delivers, over and over. I've also been using **GLM 5.2** on OpenRouter (check my previous blog for that one) — great model, really *thick* in the good way. The one real downside of the Go plan: **no Hermes-agent access.** You can't hook the subscription's API into your own agent. I was genuinely planning to wire my Hermes agent to it, and I can't — so that stays half-built for now. If the $1 Go plan ever opened up API access for a custom agent, it'd be unbeatable. I've linked the pricing and my actual token usage below so you can see it for yourself. ![Command Code pricing tiers — the $1 Go plan, $15 Pro, and $100 Max](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJLYIW96cGODv8zKEuQRClSiYAsbdfeG73ThV1) **Pricing:** [commandcode.ai/pricing](https://commandcode.ai/pricing) ![My real Command Code token usage across the budget models](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJoA7sIAf5cFEHfqaQ1VpPtBs7YTRm3hZlNOAy) ## Deal #2 — Command Code Pro ($15) and Max ($100) If you want to move up, Command Code has a **Pro plan for $15** that gets you around **$120 of usage** — roughly 25,000 requests, access to their premium open-source models, plus a Discord community and support. (I had the name wrong in my head at first — it's the Pro plan, not "Zen.") Above that, there's a **Max plan for $100** that stretches to about **$600 of usage.** They are subsidizing these models *hard*, and it's a seriously good deal. There's also a **pay-as-you-go** route — $15 to get going, then you pay their API rates — along with team and custom plans. I'll keep the pricing links in the post so you can check the current numbers yourself, since these things move. ![Command Code vs OpenCode — the setups side by side](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJLWyy9lGODv8zKEuQRClSiYAsbdfeG73ThV1q) ## Deal #3 — OpenCode Now the third one: **OpenCode.** The models are pretty similar, but the harness is the story here. Command Code is a **closed-source** harness — a CLI and an extension. OpenCode is the **free, open** alternative to Claude Code and every other harness out there: you can run it on their subscription, or bring your own API keys. On pricing, OpenCode gives you a **Go plan around $5** (bump it to $10), or a **Zen plan at $20.** Both are fine, but I don't think $20 is worth it for what we're aiming at here — **the $10 Go plan is the sweet spot.** You get a better desktop app, a much more mature CLI, an actually open community, and a project that keeps pushing forward. **Dax**, the main contributor and developer, is spot on — if you follow him on X, his agentic work is genuinely some of the sharpest out there. **So here's the play:** start with Command Code, grab that $1 deal, and ride it until it's used up — you're getting the same class of models, the same behavior, the same edge cases. Then, once you're convinced OpenCode is a worthy alternative, jump over — your first month there runs about $5. **Links:** [opencode.ai](https://opencode.ai/) · [commandcode.ai](https://commandcode.ai/) ![OpenCode running one of the budget models in my workflow](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJxTAWXvl9R3riI0XzKFH7a5TLmpyJl1P2Eewu) I actually put OpenCode through its paces in my previous post — the GLM review — so go check that out to see how it behaves. And pay attention to this, because it matters: **these models produce noticeably different output from one harness to the next.** Same model, different wrapper, different result. ## A quick word on harnesses — because this is the real game If you don't know what a harness is: a harness is basically the wrapper application — a terminal or a desktop app — that the AI model and its APIs live inside. It sends the requests and executes what comes back. It's the thing between you and the model. And harnesses are *not* equal. In my experience, the Claude Code harness is honestly a bit of a shitty one — it's riding high mostly on benchmarks. Cursor is really, really expensive and really, really good. OpenCode sits right underneath the top tier and it's closing the gap fast. There's a longer tail below that too. I don't have hard analytics on Command Code, but from actually using it, it's solid. Here's the thing most people miss: **building your own harness is not easy.** It takes real time and real passion. But that's exactly where the competition is right now. If you can build a good harness on top of solid API providers — Fireworks, or a platform's own Zen-style models — and find a host willing to hand out subsidized credits to a growing user base, then you've got something special on your hands. The whole battle is happening in the harness layer. And while that battle plays out, our job is simple: grab these tools and push them as far as they'll go. ## So here's how I'd actually play it Don't overthink the money. Start at $1 with Command Code and let DeepSeek V4 Flash surprise you. Wire it into a team with Codex or Fable as the orchestrator. Point it at real problems in a real codebase — not toy prompts — and watch how much it gets right. When you've squeezed the Go plan dry, step up to OpenCode's $10 tier and keep going. But remember what this whole post is really about. The deals are the easy part. The part that keeps you employed — the part that keeps you *ahead* — is understanding how the systems actually work underneath all this. Use the agents, learn from them, experiment relentlessly, and get seriously good at what you do. That's the price of thought. Pay it, and you're one step out the door while everyone else is still arguing about the subscription price. Until then — go break something. --- # I Tried Running a Local LLM on a 16GB MacBook Pro for Coding — Here's What Happened - **URL**: https://www.rafay99.com/blog/local-llm-are-not-the-future/ - **Published**: 2026-07-13 - **Author**: Abdul Rafay - **Tags**: AI, Artificial Intelligence, Local LLM, LLM, Open Source AI, Open Weight Models, AI Coding, Developer Tools, Machine Learning, Apple Silicon, MacBook Pro, LM Studio, Qwen, Generative AI - **Description**: Can a base M4 MacBook Pro with 16GB unified memory run local LLMs for coding? I tested Qwen, LM Studio, and OpenCode to see what works and what fails. Local LLMs suck. That's a big statement, and it's a bold claim, but it's kind of true. My Claude subscription just ran out. For an entire week, I managed to burn through my usage in just two days, and now I'm stuck coding manually because I'm not about to spend another $200 on a new account. I can wait a week and do a lot of the work myself. While doing that, I had an interesting idea. Why not try a local LLM? They seem promising. I've seen a lot of videos where people say that local LLMs are the future. There are models like Gemma 4 from Google, Qwen 3.5, Gemma 2.6 and 2.7, and GLM models that are widely available and can supposedly run on your own machine. But the reality is that most developers have fairly ordinary computers: 16–32 GB of RAM, 1 TB of storage, a mid-range CPU, and maybe a dedicated GPU. Some have an Intel Core i7 from the 12th or 13th generation, while others use a base MacBook or another lower-end machine. Not everyone can afford a $2,000–$5,000 AI workstation. So the question is: what can we actually run on these ordinary machines? Can we realistically use a local LLM? Well, the answer is a little more complicated—and a little more interesting. Before we begin with anything else, I want to be 100% clear that I love open source, and I think these **open-weight models** are incredibly important for competition and innovation. They push AI development forward much faster, and there's no doubt that, without them, the industry wouldn't be as far ahead as it is today. With that said, let's dive in. # TL;DR Local LLMs have improved dramatically, and yes, you can run them on normal consumer hardware. A laptop like my base M4 MacBook Pro with 16 GB of unified memory can run smaller open-weight models such as Qwen 3 8B and similar models without much trouble. However, running a local LLM and having a useful AI coding assistant are two completely different things. These smaller models are excellent for lightweight tasks like fixing grammar, generating Git commit messages, summarizing notes, organizing knowledge bases, and handling simple coding assistance. The limitations become obvious when you move into serious software engineering workflows. Large codebases, multi-file debugging, complex refactoring, image understanding, and advanced tool usage require larger models with bigger context windows and significantly more hardware. Local LLMs are not truly free. While the models themselves may be open and downloadable, the hardware, electricity, maintenance, and setup time all come with a cost. For developers who enjoy experimenting and building their own AI workflows, local LLMs are exciting and valuable. But for most developers looking for a replacement for tools like Claude, GPT, or other frontier AI assistants, consumer hardware still has a long way to go. ## Can You Actually Run a Local LLM? The short answer is **yes**. You can absolutely run different LLMs locally on your machine. For example, if you have an **NVIDIA GPU with around 4–8 GB of VRAM**, you can comfortably run models like **Phi-4 Mini**, **Qwen 3 8B (Q4)**, and other lightweight coding models. These are perfectly suitable for simple developer workflows such as single-line code autocompletion, basic code refactoring, Git commit message generation, and other lightweight programming tasks. Their biggest limitation isn't necessarily speed but their relatively small context window and limited reasoning ability, which makes them less effective once your project starts becoming more complex. As your hardware becomes more capable, the size of the models you can run also increases. Machines with **12–16 GB of VRAM**, such as an **RTX 4060**, **RTX 5070**, or even an **M5 Pro MacBook Pro with around 18–24 GB of unified memory**, can comfortably handle coding models in the **14B to 24B parameter** range. Models like **DeepSeek Coder V2 Lite** and **Qwen 2.5 Coder** become practical choices here. At this level, local models become genuinely useful for everyday software development. They are capable of reviewing multiple files, generating unit tests, completing larger functions, refactoring existing code, writing documentation, and assisting with medium-sized software projects without constantly running into context limitations. If you move into the **24 GB VRAM** range, such as an **RTX 5090**, or use a machine like an **M5 Max with 64 GB of unified memory**, you can start running much larger reasoning models such as **Qwen 3 32B** or **DeepSeek R1 Distill 32B**. These models are capable of handling significantly more complex workflows, including real-world debugging sessions, tool calling, code analysis, type-safe API generation, software architecture discussions, design planning, and much longer reasoning chains. At this point, local models begin to feel much closer to what cloud-hosted AI assistants can provide. Finally, if you own extremely powerful hardware, such as **dual RTX 5090s**, multiple enterprise GPUs, or cloud instances equipped with high-end accelerators, you can realistically run models in the **70B+ parameter** category. Models like **Llama 3 70B** and larger variants of **DeepSeek R1** become practical. These models are designed for large-scale architecture planning, complex system design, enterprise-level refactoring, long-running reasoning tasks, and even multi-agent software engineering workflows. ## Hardware Overview | Hardware Configuration | Typical Model Size | Practical Use Cases | | ---------------------------------- | -----------------: | ----------------------------------------------------------------------------------------------------- | | 4–8 GB VRAM | 3B–8B | Autocomplete, Git commit messages, basic refactoring, lightweight coding assistance | | 12–16 GB VRAM | 14B–24B | Multi-file coding, unit testing, documentation, function refactoring, day-to-day software development | | 24 GB VRAM or 64 GB Unified Memory | 32B | Debugging, code analysis, architecture discussions, API generation, long-context reasoning | | Dual RTX 5090s or Enterprise GPUs | 70B+ | Large system design, enterprise refactoring, planning, complex reasoning, multi-agent workflows | ## The Reality of Open Models That is the biggest advantage of owning more powerful hardware—you gain access to significantly larger models. However, despite how impressive these open-source models have become, they still don't come close to **GPT-5.5**, **Codex**, or **Claude Opus** when it comes to overall reasoning ability, coding performance, and consistency. The gap is certainly getting smaller. Every few months, models like **Gemma**, **Qwen**, **DeepSeek**, and **GLM** continue to improve. With each release, they catch up a little more to today's frontier models. However, by the time they approach the capabilities of the previous generation, companies like OpenAI and Anthropic have already released another generation of even more capable models. As a result, the gap, although shrinking, still exists. ## Different Models, Different Strengths Every one of these models comes with its own strengths and weaknesses. They differ in architecture, training methodology, tokenizer design, context length, quantization support, and hardware optimization. Some are better at coding, others excel at reasoning, while some are designed specifically for multilingual tasks or long-context workloads. Many of the newer Chinese open-source models are also trained using hardware that differs significantly from the NVIDIA-centric infrastructure most developers are familiar with. They often rely on domestically developed AI accelerators and entirely different training stacks. That is a fascinating topic on its own, but it's also a discussion that's beyond the scope of this article. ## The Question That Actually Matters So the real question isn't whether local LLMs can run on consumer hardware—they clearly can. The real question is this: if I'm using a **base M4 MacBook Pro with 16 GB of unified memory**, can I realistically run a local model that helps me with everyday junior developer tasks? Can it write Git commit messages, organize my Obsidian vault, manage my notes, build a personal wiki, summarize documentation, and generally help me organize my thoughts? These aren't particularly difficult tasks, but they're important enough that I don't necessarily want to spend **Claude Opus** or **GPT-5.5** money on them every single day. And if the answer is yes for me, then can my teammates with similar laptops use the exact same setup as well? # Setting Up a Local LLM on a Mac With all that said, let's actually put it to the test. As I mentioned earlier, I'm using a **base M4 MacBook Pro with 16 GB of unified memory**. The obvious question is: **can I run a local LLM on this machine?** And if I can, **how exactly do I do it?** With that question in mind, let's start from the basics. To run any local LLM on your machine, you need three things. First, you need the **model** itself. Second, you need a **server** that can load and serve the model. Third, you need a **client or interface** that communicates with the server, sends requests to the model, and integrates it with your coding environment or other applications. There are countless options available for each of these components. The internet is full of different model repositories, inference servers, and desktop applications, each with its own strengths and weaknesses. However, if you're using a **Mac**, there is one technology that stands out: **MLX**. MLX is Apple's machine learning framework designed specifically for **Apple Silicon**. Many open-source models are converted into the **MLX format**, allowing them to take full advantage of Apple's unified memory architecture. Instead of relying solely on GPU memory, MLX enables the CPU and GPU to efficiently share the same pool of memory, making it possible to run surprisingly capable models even on base MacBooks. If you're on **Windows**, however, the story is completely different. # Installing LM Studio and Setting Up My First Local LLM With the theory out of the way, it was finally time to see whether this would actually work on my machine. I started by installing **LM Studio**, and the installation process was surprisingly smooth. After downloading the application, it walked me through a short onboarding process. One thing I really liked was that LM Studio automatically detected my system specifications, including the amount of unified memory and the overall hardware available. Based on those resources, it recommended a model that it believed would run well on my machine. In my case, it suggested a **Gemma 3** quantized model. However, before downloading anything, I asked ChatGPT which local model would be the best choice for my hardware. My primary goal wasn't to replace Claude or GPT-5.5—I simply wanted something capable of handling lightweight development tasks such as writing Git commit messages, reviewing pull requests, performing simple code reviews, and helping with other junior-level development work. The recommendation was **Qwen 3 8B**, quantized to **Q4**, which is generally considered one of the best performance-to-memory trade-offs for consumer hardware. That sounded reasonable, so I downloaded the model. ![qwen model.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJlo2tfBOwnMSaAmJh8r0o2yIjlPqUTZEsuO7H) Once the download was complete, I increased the model's context window to the maximum value that LM Studio allowed. After that, I installed **OpenCode**, which would act as the client—or, more accurately, the harness—for interacting with the model. As I mentioned earlier, there are three pieces involved in running a local LLM. First, there's the model itself. Second, there's the inference server that loads and serves the model. Finally, there's the client application that communicates with that server and provides a usable interface inside your coding workflow. In my setup, **LM Studio** handled the inference server, while **OpenCode** became the interface that streamed responses and integrated with my development environment. ![1-setting-open.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJLMTZTjGODv8zKEuQRClSiYAsbdfeG73ThV1q) ![2.other provider.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJTVZE1PoJnLIJBWPvUF7zO3g50aD6HtkNEXpR) ![3.Enter-api-key-connected.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ6wBMfIDA41iteuNTf5x0RzW7oh6IpZyFvlCM) Once everything was installed, the remaining setup was straightforward. Inside LM Studio, I opened the **Developer** tab and enabled the local server. By default, it started an OpenAI-compatible API server on **localhost:1234**, which meant any compatible client could immediately connect to it. ![LM Studio Local Dev Server.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJffCwxBgM2Y36kmGTvR8NgZEHqahLDpX9VzJA) The model booted without any issues. Before using it, I enabled a few performance-related options, including **KV cache** and **parallelism**, to squeeze a little more performance out of the hardware. After that, I started chatting with the model directly inside LM Studio just to verify that everything was working correctly. One thing became immediately obvious, though. Unlike cloud services, this isn't a serverless environment where resources are allocated on demand. The entire model is loaded directly into your machine's memory. On my **16 GB M4 MacBook Pro**, my memory usage jumped from around **5 GB** with just my browser open to roughly **11–12 GB** as soon as the model finished loading. That's a significant increase, but it was still manageable and left enough memory for the rest of my development workflow. ![Model-Loaded-in-memory.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ8Gew0AtmYFqJTthG6XHUrp5nyDRAkMsBZ4v3) With the server running, I switched over to OpenCode, entered the local API URL, configured the API key, selected the model, and finished the remaining setup. Within minutes, everything was connected. The first few interactions were surprisingly smooth. I could send prompts, receive streaming responses, and use the local model almost exactly like I would use a cloud-hosted API. At that point, I finally had a fully working local coding assistant running entirely on my laptop. ![model-is-working.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJkQHbiv3iDowrFjuG5fYXpRx8zcT73VgyUQe2) ## The Downsides And there you have it—the model was finally running on my local machine. I could chat with it, ask questions, and use it just like any other AI assistant. Honestly, I could have ended the blog post right there. But there are downsides. You probably already know the biggest one: **your hardware**. Even on my base machine, yes, I can run these models. But here's the thing—they're simply not good at complex tasks. By "complex," I mean giving the model an entire TypeScript codebase and expecting it to find bugs, explain the issue, and fix it. I actually tried this with **Wryte.xyz**, the platform I built for writing and scheduling content. I gave it a fairly simple prompt, almost identical to something I'd normally send to Claude: > In this project, when I am writing content and hit the Publish button, if the text length is too long, the content spills out of the dialog box, causing poor UI and UX. Can you resolve this UI/UX bug for me? And before anyone comments, yes—I know I could fix a bug like this myself. I was bored, I was lazy, and that's exactly why I wanted to see how capable these local LLMs really were. The result was... disappointing. **![the model failure.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ3Ae167SjiW4rwlthXG3mf0Y6AH1TgoNkdnep)** Yeah... it didn't work. Part of that was my fault. I hadn't configured the context window properly, and the model I chose didn't support images. Even if it had, the context window was simply too small to understand the entire project or make reliable tool calls. That's when I realized what these smaller models are actually built for. They're great as chat models. They're good at fixing grammar, rewriting text, writing Git commit messages, summarizing notes, or handling the small jobs that don't justify spending Claude or GPT money. But asking them to reason through an entire production codebase is expecting far too much—at least on consumer hardware. Sure, with significantly more RAM and a much larger GPU, the story changes. But I'm trying to stay realistic. Most developers—probably 80% of us—aren't building dedicated AI workstations. We just want tools that work on the laptop we already own. There's another thing nobody really talks about either: concurrency. During my testing, everything was basically one request at a time. I couldn't comfortably run multiple sessions, and that became frustrating very quickly. And please, for the love of God, stop saying local LLMs are "free." The model might be free to download, but the hardware isn't. Neither is the electricity. If you're tying up an expensive machine all day running inference, you're paying for it somehow. So, are local LLMs worth it? Absolutely—if you enjoy tinkering. They're fantastic for learning, experimenting, and handling lightweight everyday tasks. But if your goal is serious end-to-end software engineering, large-scale coding, image generation, or video generation, then on ordinary consumer hardware, they're simply not there yet. There are plenty of YouTube channels that go much deeper into local LLMs and hardware optimization, so if this interests you, they're well worth watching. Anyway... this turned into a much bigger rant than I expected. Until next time, **Goodbye, nerds.** # Frequently Asked Questions (FAQ) ## Can I run a local LLM on a normal laptop? Yes, you can run local LLMs on normal laptops. Machines with 16 GB to 32 GB of RAM can run smaller open-weight models, especially quantized versions. However, the size and capability of the model depend heavily on your available memory and hardware. ## What is the best local LLM for a 16 GB MacBook Pro? For a 16 GB MacBook Pro, smaller quantized models like Qwen 3 8B, Gemma, Phi, and similar models are good options. They are suitable for lightweight coding tasks, writing assistance, and personal productivity workflows. ## Can a local LLM replace Claude or GPT for coding? Not on most consumer hardware. Local LLMs can handle simple coding tasks, but they struggle with large codebases, complex debugging, long context understanding, and advanced software engineering workflows compared to frontier cloud models. ## Are local LLMs actually free? No. While many open-weight models are free to download, running them requires hardware, electricity, storage, and maintenance. The cost is transferred from cloud subscriptions to your own infrastructure. ## What hardware do I need to run a good local coding LLM? It depends on the model size. Smaller models can run on 8–16 GB of memory, while larger coding and reasoning models often require 24 GB, 48 GB, or more of GPU memory. ## Are local LLMs good for software developers? Yes, but mainly for specific tasks. They are useful for generating commit messages, explaining code, writing documentation, summarizing information, and assisting with small coding tasks. They are currently not a complete replacement for advanced AI coding assistants. ## Why are local LLMs slower than cloud AI models? Cloud AI providers run models on large clusters of specialized hardware. A local machine usually has much less compute power, meaning smaller models, slower inference, and fewer simultaneous requests. ## Should developers use local LLMs? Developers should use local LLMs if they want privacy, experimentation, customization, or lightweight AI assistance. For complex development workflows, cloud-based AI models are still generally more capable. --- # Issue Tracking Is Dead: Rethinking Project Management in the Age of AI - **URL**: https://www.rafay99.com/blog/ai-project-management/ - **Published**: 2026-07-11 - **Author**: Abdul Rafay - **Tags**: AI, Project Management, Developer Tools, Software Engineering, Open Source, GitHub, GitHub Issues, Linear, Jira, Notion, Claude Code, Codex, Local LLM, Developer Productivity, AI Workflow - **Description**: Traditional issue tracking tools like Jira, Linear, GitHub Issues, and Notion were designed for a world where humans manually planned and implemented software. AI is changing that. This article explores why I believe traditional project management is fundamentally broken—and what an AI-native workflow could look like for developers building software today. We are in a stage of AI development where everything we need to do has to be rethought: how we arrange our thoughts, how we build software, and how we deploy software. It's a time where we need to take a sledgehammer, bring it all down, and make sure that everything is new and exciting in a way. The same goes for my thought process and my planning phase as well. ## TL;DR Artificial intelligence is forcing us to rethink more than just how we write code. It's changing how we organize our thoughts, plan features, manage software projects, and collaborate with our tools. After years of using GitHub Issues, Linear, Jira, Notion, and countless productivity systems, I've realized they all suffer from the same problem: friction. Instead of managing tickets, I want to describe what I want to build in plain English and let AI understand the project, generate implementation plans, identify edge cases, and even hand the work directly to coding agents like Claude Code or Codex. This isn't a finished product—it's an idea. But I think this is where software development is heading. ## Context So, a little bit of context here. I have a lot of open-source projects that I love to work on. I have Virtual, Crisp, Portal, Quinn, envpilot.dev, Lumo, and a bunch of other applications and projects that I really love. But managing all of them—managing all the bugs, issues, and new features—is a pain. It's not good. It's a pain in the ass to deal with. I have tried multiple planning and project management tools. Either they are way too complex, or they require too much setup, and you get trapped in an infinite loop where you keep iterating and reiterating. Then, when it's finally time to use them, you never do. ## The Productivity & Notion Trap I saw a video online from a YouTuber, I think they're called [**Efficient App (Alex & Andra)**](https://www.youtube.com/@efficientapp), and they pointed out the trap of [**Notion**](https://www.youtube.com/watch?v=ERarYs2KVPI) and other similar tools. That's exactly where I see myself. I set up Notion with boards and dashboards everywhere, and what happens at the end of the day is that, after everything is set up, I don't use it that much. In that video, they explained how Notion uses its online presence to create this urgency that it is the one platform and tool for everybody. That can be true for some purposes, but not for others. They went deep into how things are set up and where things are going, but the main point for me was that I completely agreed with their viewpoint. It was a solid eye-opener. And this is not the only video out there. Even Linear, which has been one of the ultimate issue-tracking tools alongside Jira that I've used in the industry for many years now, is coming out with its own blog post saying that issue tracking is kind of dead. Here is the official blog post from [Linear](https://linear.app/next). And as you can see, things are really changing. But how we're going to interact with these tools is still a big problem. We understand that there has to be some kind of tracking. There has to be some kind of backlog. There have to be new features, and there have to be bugs that need to be tracked as well. But with the rise of AI, Codex, Claude Code, and these new Chinese models, we can do a lot more in a much more fun and creative way to figure out which things are going in the right direction. The old method of project management is completely broken. Here's the thing. A normal project manager goes to the client and figures out what's missing. They work with a business analyst, a business manager, or a strategy team. Then they go to the business and start identifying how things are going to work, what the current flow is, what needs to be solved, and how the process should work. They define the processes, decide what features need to exist, and once they have everything they need, they create documents like system diagrams, SSDs, system design documents, or follow Agile methodologies. Then they go into an issue-tracking tool like Linear, Jira, GitHub Issues, or GitHub Projects. They set everything up, create the sprints, assign a bunch of tickets to developers, and the team starts building the project. Once features reach a certain stage, they move to QA to make sure everything works from development to staging to production. This has been the monolithic structure for years, even before the age of AI. Now things are in a place where I can clearly see that issue tracking is fundamentally broken. There is no way on earth that we're at a stage where this is still the best way to do things. Linear even said that issue tracking is dead, as you can see in their blog post. Jira hasn't come out with any kind of statement yet, but this is definitely something we should be thinking about. And I realized that I spend one or two months setting up a tool, then I use it occasionally, but there is always one little friction point that matters a lot. After that, all the other work really doesn't matter anymore, and I stop using the tool altogether. That was their point of view, and I kind of see it not just with Notion but with every little problem that I try to solve. Every piece of software I try has that one little friction point when trying to build a second brain—a place to dump thoughts in a way that they can be organized, searched, and easily manifested. And I'm at a point where I do not want to build another tool, but maybe I'll find another tool that fits my requirements. Or maybe I should see this as an opportunity to make something happen. Another aspect that matters to me a lot. ## The big idea So let's talk about the idea. How do we solve this problem? Because we have identified the cost. We build or set up certain tools, we use them for a while, but then that little friction point appears, and we abandon them. **For example**, this platform I'm writing this blog post on, wryte.xyz. I use it on a daily basis. It's a tool that I thought I might use once or twice, but now I'm using it almost every day for writing all of my content, all of my blog posts, and all of my ideas. I love it because there isn't a friction point for me. It's a wholesome experience. I removed a lot of manual work from my life by writing blog posts on one consolidated website where I can just hook everything up and make things happen. It's still not polished enough. There are still little things that need to be improved, but they are side issues and not a big deal for me. Ninety percent of my work for writing content can be done there. But for managing all of my projects, it's not the same thing. I have tried GitHub Issues, backlog.md, Linear, and even Notion, but none of them fit into the category that I'm looking for. ## The Solution So what's the solution? Here's what I'm thinking. It's going to be a simple text box where I'll sign in with my GitHub account and get access to all of my GitHub projects. I'll select certain projects, or maybe all of them, and there will be a small local LLM that gets context from each repository—for example, by reading the README or something similar. Maybe it gets the project names and stores them permanently in its memory. Then I just open the web app or desktop application—I don't know which platform I'm going to go with right now—and I'll say: > "EnvPilot, I need to add a new feature. I need to add a GitHub Action for this project." For example, if anybody wants to fetch their environment variables for builds, production, or anything else, they can do that. Then the AI model, or the local AI model, understands that I'm talking about this specific project. It already knows the project, understands the feature I want to build, identifies multiple edge cases, creates a rough plan, maybe a rough schema diagram, and generates the to-do list, scheduling, and estimated time required. Then there will be a small Kanban board with four or five stages: **To Do**, **Started**, **Review**, **Merged**, and **Completed**. There will also be a button. If I click that button, since it's already linked to my GitHub account, it can create a bunch of GitHub Issues or future plans automatically. Although I've come to realize that GitHub Issues are fundamentally broken, and I don't really want to deal with them. So that's one possible direction. Maybe it could be a desktop application built with Electron. I could use Convex, TypeScript, Effect, and tRPC to make sure every single piece is working properly. There could also be a button that says **"Implement this feature in Claude Code."** When I click it, it would trigger my terminal, open Claude Code, and inject the basic description automatically. Something like: > "This project is in my metadata. Here is the feature that I want to implement. Go do your research and implement it." That way we can also use the LLM to detect defects, identify edge cases, and maybe have a notes and description section where I can edit things manually if I want. Or I could have a full recall system powered by an LLM where I can simply ask: > "What's my to-do list for this project?" And it gives me a dead-simple answer. Keep it vibey. That's the kind of vibe and experience that I'm looking for. I don't know if this is a perfect solution or not. I don't know whether it's going to work. I also don't know how I'm going to monetize this app because I really don't want to integrate Claude SDKs or OpenAI SDKs and then charge for API keys. That's an expensive bill that might come my way, and I don't want to deal with that. I would really prefer a desktop application. Maybe Electron, or maybe Deno. I heard Deno is a really good framework for this. If I go with Electron, I can support both macOS and Windows. I don't want to go with SwiftUI anymore. I've already been there, and maintaining one application after another is kind of a nightmare. I could charge a one-time lifetime fee that includes updates, open-source it as well, and use local LLM models so everything runs really fast. If a system isn't capable of running a local LLM, then we can switch to an API provider. Having a **Bring Your Own API Key** section would be a much better approach. So that is my entire plan, thought process, and brain rot that has been happening over the last couple of days. I've been thinking a lot about how we can manage projects better and where things are going. But let's see. Until then, see you next time, nerds. --- # A Month With GLM 5.2: Cheap, Relentless, and Blind - **URL**: https://www.rafay99.com/blog/a-month-with-glm-52-cheap-relentless-and-blind/ - **Published**: 2026-07-08 - **Author**: Abdul Rafay - **Tags**: GLM, GLM5.2, OpenCode, AICoding, OpenSource, ThoughtsProcess - **Description**: I ran GLM 5.2 as my daily coding agent in OpenCode for a month — full OpenCode Go subscription, wired in as my Hermes agent. It fixed real performance and battery bugs in my macOS app Vitals (CPU ~89% down to ~13%, 143/143 tests passing) for a few dollars a session. But it can't see screenshots, it's a token glutton, and on pay-per-token it burned through $10–20 of Fireworks credits fast. Here's the honest month-long review: what it's great at, where it falls apart, and why at ~$10 nothing else touches it for coding. I told you at the end of the Fable 5 post that I had a pile of GLM 5.2 notes and a whole write-up coming. Here it is. I've been running GLM 5.2 for a month straight — not a weekend trial, a month of real work inside OpenCode. I'm on a full subscription now, and GLM 5.2 is wired in as my Hermes agent, my default core agent for basically everything. Setup was painless. Point OpenCode at the Go provider, pick GLM-5.2, done. And here's the short version before I get into it: this is the best value in AI coding right now, full stop. It's also blind, hungry, and unoptimized in ways that'll make you wince. Both things are true. Let me show you. ## TL;DR — the short version - **What:** GLM 5.2 is Z.ai's open-weight coding model. I ran it for a month as my main agent in OpenCode, on the **OpenCode Go** plan ("low-cost coding models for everyone"). - **What it's great at:** code review, writing code, searching a codebase, and — surprisingly — knowing *when a problem is above its pay grade*. It's relentless: it diagnoses a bug, fixes it, runs its own shell and smoke tests, and loops until it's actually solved. - **The proof:** it root-caused and fixed three real bugs in my macOS app **Vitals** — a chart-rendering stall (**history-scroll CPU ~89% → ~13%**, 126/126 tests passing), a nav-bar lag on the Processes tab, and a battery drain (**143/143 tests, ~50% fewer wakeups on battery**). Each session cost a few dollars of metered compute. - **The catches:** it **can't see images or screenshots** (no multimodal — a real problem for UI debugging), it's a **token glutton**, and it's **unoptimized**. On pay-per-token (Fireworks) it ate $10–20 of free credits at a speed I still can't quite believe. - **The verdict:** if you've got a ~$10 budget for coding, there is nothing better. I get 90% of my work done with it. Use **OpenCode Go**, not Zen. ## Quick answers **What is GLM 5.2?** An open-weight coding model from Z.ai (the GLM series). It dropped before Fable 5 came back, got a big wave of hype on X, and the pitch was that it goes toe-to-toe with the frontier on benchmarks at a fraction of the price. **How do I run it?** Inside OpenCode, on the OpenCode Go subscription. Select "OpenCode Go" as the provider in your config, pick GLM-5.2, and it becomes your agent. I set it up as my Hermes agent and it's been my default for a month. **What does it cost?** The Go plan is cheap — think $5 to start, ~$10/month once you're in. Individual sessions meter a few dollars of compute against your rolling/weekly/monthly usage. On raw pay-per-token providers it's a different, scarier story (more below). **Is GLM 5.2 as good as Opus 4.8?** For a big chunk of day-to-day coding, review, and search — close enough that the price gap stops mattering. For anything visual, or anything needing heavy reasoning and optimization, no. That's the honest line. **Can GLM 5.2 see screenshots?** No. No image support. It told me so, mid-session, when I pasted a screenshot of a laggy nav bar. That's its single biggest limitation. **When did I use it?** Across June 2026, mostly on my Vitals codebase, before and around the Fable 5 saga. All the numbers and screenshots below are from those sessions. ## Setup and the first impression OpenCode itself is clean. I mean it — the desktop app is genuinely nice to sit in, and the way it streams the model's thinking live is a big part of why I stuck around. You watch GLM 5.2 reason its way through a problem in real time instead of staring at a spinner. ![opencode-go-plan.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ4UTAdCiFLOXl3ypochkavemWz6wDQUIAdKrf) The Go plan is the whole pitch: low-cost coding models for everyone. You get rolling, weekly, and monthly usage meters instead of a raw per-token bill, which — for a token-hungry model like this one — turns out to matter a lot. So I did what I always do with a new model: I threw a real, annoying bug at it. ## The test: can it actually fix my app? The hype said GLM 5.2 was on par with Opus 4.8. Fine. My macOS system monitor, **Vitals**, had a real performance problem: when a lot of data loaded, the app lagged hard at peak. I knew Claude could fix it. The question was whether this cheap model could. Four prompts in, it had found the root cause on its own. ![root-cause-appiconcache.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJfWthl1ugM2Y36kmGTvR8NgZEHqahLDpX9VzJ) > Root cause confirmed: `AppIconCache.icon(for:)` runs `NSWorkspace.shared.icon(forFile:)` synchronously on the main thread. Each visible `ProcessRow` loads via `.task`, so ~15–20 icon loads serialize on the first frame — that's the lag. That's not a guess. It read the code, traced the call path, and pointed at the exact synchronous call blocking the main thread. Then it fixed it and verified the fix with its own shell tests — switch-back latency, scroll CPU, the works. It even showed the commands it ran right there in the terminal view, which I love. The result shipped as a focused pull request: ![pr-66-summary.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJd35fCipRMXrVqxvoCAZgBiLEyI8peGwKtDH1) Four files. +146/−56. History-scroll peak CPU went from **~89% to ~13%**, AX latency flat, **126/126 tests passing**. You can see the actual PR here: [Vitals#66](https://github.com/rafay99-epic/Vitals/pull/66). And here's the part that told me this model has real taste: it also *prototyped* a bigger `@Observable` migration, hit genuine framework friction (mixing `@Environment` and `@EnvironmentObject` breaks the synthesized initializer, ~25 child views wouldn't compile), and then **reverted it** and shipped the low-risk fix instead — documenting the bigger change as a follow-up. It knew when to stop. That restraint is rare. One thing I noticed in the PR: it only touched **6 files** across the session and nothing more. That's a very GPT-flavored behavior — surgical, stays in its lane, doesn't go rewriting half your repo to feel productive. I like it. ## Where it earns its keep After a month, here's what GLM 5.2 is genuinely good at: **Code review and coding.** It writes solid code and reviews it well. This is the bread and butter and it just works. **Searching a codebase.** Point it at a repo and it finds the relevant thing fast. Its "explored / N reads" grep-and-read loop is efficient. **Being relentless.** This is the underrated one. It verifies, and re-verifies, and re-verifies again until the problem is actually solved. It *can* get stuck looping over tokens if it's not careful — but in my month with it, it didn't. It kept its head down and finished. The battery drain job is the cleanest example. Vitals was eating too much power on my Mac. I described the symptom, and GLM 5.2 traced it to the polling loop itself: ![battery-drain-diagnosis.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ2mNbayzNlCFs7RaDUjr1gkAhYuLmT9ZtyS0w) The diagnosis was specific: `VitalsModel.tick()` fires on a fixed timer every couple of seconds and does the full sweep — temps, fans, CPU, memory, GPU, power — with no awareness of whether you're on battery, in Low Power Mode, or whether the lid is even open. So on battery it keeps IOKit and the SMC busy every 1–2 seconds with the screen off and nobody looking. That's the drain. Then it built the fix — pause sampling on sleep, a power-aware adaptive interval, back off when the window's closed — and verified it end to end: ![battery-fix-verification.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJtAURtV5Tkd73eKjcbxAusS1ZaL02X5lBpmzU) **143/143 tests passing**, zero lint violations, ~50% fewer wakeups on battery, and it even respected my `AGENTS.md` — no AI attribution in the commits, credited to my company. That's a production-ready change from a $10 model. ## The catches (and they're real) Now the part where I stop gushing. **It's blind.** GLM 5.2 has no image support. None. This isn't a minor gap — when I was chasing a nav-bar lag on the Processes tab and pasted a screenshot, it just told me flat out: ![no-image-support.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ1kQ36ZdndGSeJU7Linmr2fx6NbADtpOXg3jR) > I can't read the image (no image support on this model), but I understand the symptom: the nav bar itself lags when switching to/from the Processes tab. To its credit, it reasoned its way to the fix from the code alone and solved it. But for UI work — where half the bugs are "look at this, it's wrong" — being unable to see a screenshot is a serious handicap. **This is the number-one thing Z.ai needs to fix.** Give it eyes. Let it see what things actually look like. Half the debugging loop opens up the moment it can. **It's a token glutton.** Look at the session accounting: ![session-cost-6-dollars.webp](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJ37oB27SjiW4rwlthXG3mf0Y6AH1TgoNkdnep) That's **214,922 tokens and $6.01 of metered compute for one session** — and that's a fairly typical one. My sessions ran roughly $3.50 to $6 each. Now, the caching is genuinely good: the first run on a new project is heavy, but after that the cache-read numbers are huge and the effective spend drops. The Go subscription absorbs this into usage meters, which is exactly why the plan works. But make no mistake — this model *eats*. **On raw pay-per-token, it's brutal.** I ran GLM 5.2 through my Hermes agent on **Fireworks AI**, which handed out about $10–20 in free credits. It chewed through that budget off the clock. I cannot overstate how token-hungry and unoptimized it is when there's no subscription cap in front of it. Sometimes I had to actively redirect it to stop it from wandering. On a metered plan you don't feel it; on a raw meter, you feel every token. **It runs out.** More than once I hit my usage cap mid-flow, waited ~47 minutes for the rolling window to reset, and got back to it. Annoying, but that's the trade you make for the price. ## The routing insight Here's the thing the month taught me that I didn't expect: GLM 5.2 is weirdly good at knowing what it *can't* do. And that points at how these models should actually be used. There's an online harness I came across (the exact name's escaping me) built around this idea — you send it a prompt, it judges how hard the problem is, and it routes accordingly. Simple, mechanical stuff goes to a cheap model like GLM 5.2 or 5.1. Genuinely hard problems get escalated to a high tier — Opus 4.8, or GPT-5.x. You stop paying frontier prices for work a cheap model handles fine. ```mermaid flowchart TD A[Your prompt] --> B{Router: how hard is this?} B -->|Simple / mechanical| C[GLM 5.2 or 5.1
cheap, fast, gets it done] B -->|Complex / needs reasoning| D[High tier
Opus 4.8, GPT-5.x] C --> E[Result shipped] D --> E ``` That's the future I keep landing on. Not one model for everything — the right model for each request, with a cheap workhorse doing the bulk and an expensive brain on call for the hard 10%. GLM 5.2 is a fantastic workhorse. And this is roughly how it already behaves inside a single task, which is why it works so well on a codebase: ```mermaid flowchart TD A[You describe the bug] --> B[GLM 5.2 thinks it through
shown live in OpenCode] B --> C[Reads the codebase
finds the root cause] C --> D[Writes the fix
touches only the files it needs] D --> E[Runs shell + smoke tests] E --> F{Solved and verified?} F -->|No| C F -->|Yes| G[Opens a focused PR] G -.->|catch: can't see screenshots| H[You verify anything visual by hand] ``` With the right harness and a proper workflow, you can run the model and manage usage quite cheaply. That said, this model is surrounded by a lot of hype. Yes, it is powerful, and yes, it is very much on par with Opus 4.8—even beating it in some cases. However, there are things it simply cannot do, such as sub-agent calling, and its tool calls are not mature enough yet. Because of this, the harness you use with this model is incredibly important. Running it as a Hermes agent is not a great approach if you are paying raw API pricing. On the other hand, OpenCode—the harness I was using—is excellent, and its ability to deliver these kinds of results is awesome. ## So, is it worth it? Yes. With caveats you now know by heart. This is a big win for the Chinese open models. They matched the frontier on benchmarks and, more importantly, they get shit done. For coding specifically — on OpenCode, at $5 to start and ~$10 a month after — there is no better option out there right now. If I had a $10 budget and that was all I could afford, I'd go straight to **OpenCode Go** (Go, specifically — not Zen), because that's the most cost-effective way to run these models, and I can do 90% of my work with GLM 5.2 alone. The other 10% — the visual debugging, the genuinely hard reasoning — I route elsewhere. That's not a knock. That's just using the right tool. l will be using this model mostly for code reviews via the Hermes Agent. With a 10-dollar budget, I can automate research, content creation, and code reviews using specialized GitHub Actions and webhooks. The ability to fully automate the agent has been fantastic. Other Code Review tools are more then 20 or plus withh very limited usage as well, yes this is not cheap but for me I am willing to spend this much to get a full on helper with the code review process. Give this model eyes and tighten the token appetite, and it stops being "the best cheap option" and starts being a default. Until then: cheap, relentless, and blind. I'll take two out of three at this price every day. Until next time, nerds. 👋 --- # Fable 5 Is Back. It Can't Code. It's Never Been More Useful. - **URL**: https://www.rafay99.com/blog/fable-5-is-back-it-cant-code-its-never-been-more-useful/ - **Published**: 2026-07-05 - **Author**: Abdul Rafay - **Tags**: Claude, Fable5, Anthropic, Orchestrator, AICoding, ThoughtsProcess - **Description**: Anthropic brought Claude Fable 5 back for global users on July 1 — but it's not allowed to write code, it falls back to Opus 4.8. So I used it as an orchestrator instead, ran Opus 4.8 and Sonnet 5 as sub-agents under it, and shipped fixes across three of my apps in an afternoon. Here's exactly how the orchestrator method works, what it cost, and whether it's worth it. So Fable 5 is back. It's been a few days since my last love letter — the one where I told you Fable 5 was the best model I'd ever put my hands on, and then watched the US government switch it off 48 hours later. For a while there we got nothing. No Fable, no Mythos, just a login page telling foreign nationals like me the frontier was closed. Then Anthropic worked something out with Washington — I don't know the exact terms of whatever deal got made with the White House — and on July 1 they put it back on the table for global users. Here's the tweet that told me it was live again: I've been on it for days now, and holy hell. When it first came back I wasn't impressed — the usage was going through the roof and my results were all over the place. Then I learned the one trick that changes everything, and now I'm dreading July 7, the day it's supposed to get pulled from me again. Because in between, this became the best way I've ever worked. Let me explain what actually changed, because the catch is real and the workaround is genuinely brilliant. ## TL;DR — the short version - **What:** Anthropic re-enabled Claude Fable 5 (Mythos-class) for global users. But per their own announcement, **Fable 5 is not available for coding — it falls back to Opus 4.8** when you ask it to write code. - **When:** Back for everyone on **July 1, 2026**. My understanding is it's set to be taken away again on **July 7**. - **How I still ship with it:** I use an **orchestrator plugin**. Fable 5 doesn't write the code — it *runs the project*. It reads the codebase, plans the work, spawns Opus 4.8 and Sonnet 5 as sub-agents to do the coding and testing, then reviews their work and pushes back until it's right. - **Result:** In one afternoon I fixed a completely broken role-based access system across a web app, a CLI, and a VS Code extension, and ported a Mac app to Windows — across three of my projects at once. - **The catch:** It's expensive. Roughly **$5 per million input tokens and $15 per million output**, caching billed separately, and it's **not in any subscription yet** — API credits only. ## Quick answers (the what / when / how) **What is the "orchestrator method"?** It's using Fable 5 as the head of the project instead of as the coder. You install an orchestrator plugin, tell Fable it's in charge, hand it the feature you want, and let it plan, delegate to sub-agents, test, and review. It never writes production code itself — it directs the models that do. **Why can't Fable 5 code directly?** Because Anthropic's own announcement about restoring the model says so. If you ask Fable 5 to write code, it falls back to Opus 4.8. My read is this is part of the conditions attached to bringing it back — and coding was supposed to be its whole point, so at first this looked like a dealbreaker. **So why is it still worth using?** Because Fable 5 is unreal at *reading* code, planning, and catching problems other models miss. Point it at a repo and it finds the gaps, the dead code, the bad logic. That's the muscle the orchestrator method leans on. **When did it come back, and how long do I have?** Global access returned July 1, 2026. I expect to lose it again on July 7. So this whole post is written against a clock. **What does it cost?** About $5 per million input tokens and $15 per million output, with separate caching charges. It's not part of the $20 or $100 or $200 subscription tiers yet — you pay with API credits. ## The catch: Fable came back, but it's not allowed to code Here's the thing nobody warned me about. When Fable 5 returned, I did what any developer would do — I opened it up and told it to build. And the results were rough. My usage spiked, and two or three prompts in, the whole thing was a mess. I was genuinely confused. This was the model I'd written two thousand words praising. What happened? So I went to X and started digging. A few tweets from Theo, a few from other people, all pointing at the same thing — an "orchestrator" methodology. And then I went and actually read Anthropic's announcement about restoring Fable, and hit the line that explained everything: > Fable 5 is not available for coding. It will fall back to Opus 4.8. Read that again. The best coding model I'd ever used is back — and it's not allowed to write code. If Opus 4.8 is doing all the actual coding anyway, what's even the point of Fable 5? The point is this: **Fable 5 is exceptional at reading code, planning, and spotting problems.** It just isn't the one holding the pen anymore. So you don't ask it to type. You put it in charge. ## What an orchestrator actually is An orchestrator is the head that takes charge of the entire project and decides how things are going to go. It doesn't do the grunt work. It plans it, delegates it, checks it, and sends it back when it's wrong — like a senior engineer running a team of very fast juniors. I installed the orchestrator plugin, selected Fable 5, and told it plainly: *you're in charge. Here are the features I want. Use this plugin as intended. Spin up as many sub-agents as you need, and take it from planning to execution to testing to smoke tests — end to end. I don't want to babysit it.* Then I handed it the feature and walked away. Here's the shape of it: ```mermaid flowchart TD A[You: select Fable 5
install the orchestrator plugin] --> B[Fable 5 = Orchestrator] B --> C[Read the codebase
find the gaps and bad logic] C --> D[Plan the work
break it into tasks] D --> E[Spawn sub-agents] E --> F[Opus 4.8
writes the code] E --> G[Sonnet 5
tests and grunt work] F --> H[Fable reviews the output] G --> H H --> I{Good enough?} I -->|No: edge cases missed| E I -->|Yes| J[Playwright + smoke tests] J --> K[PR -> staging -> main -> migration] ``` At the same time Fable came back, Anthropic shipped **Sonnet 5** — a very good, very capable model, just not on Fable's level. So my team looked like this: Fable 5 orchestrating, Opus 4.8 and Sonnet 5 doing the building and testing underneath it. Fable would hand them work, read what came back, and give them a grade — what they got right, what they got wrong, which edge cases they handled and which they quietly skipped. Then it would send it back for another pass. ```mermaid sequenceDiagram participant You participant Fable as Fable 5 Orchestrator participant Opus as Opus 4.8 Coder participant Sonnet as Sonnet 5 Tests You->>Fable: Here is the feature and my UI components Fable->>Fable: Read the code and plan Fable->>Opus: Implement the role system Fable->>Sonnet: Write Playwright and smoke tests Opus-->>Fable: Code back Sonnet-->>Fable: Tests back Fable->>Fable: Review - what edge case did you miss? Fable->>Opus: Fix the invitation flow, reuse my components Opus-->>Fable: Fixed Fable-->>You: Feature done, tested end to end ``` That back-and-forth is the whole magic. Through a few rounds of it, they fully implemented the feature in about an hour or two. And it barely burned the tokens I expected it to. I've been working the wrong way this whole time. These models have come far enough that Fable can identify gaps on its own, revise its own plan, and test an app end to end — as long as you give it the API keys or demo credentials to work with. ## Project one: the broken role system in envpilot.dev Quick reminder of what [envpilot.dev](https://envpilot.dev) is: a platform I built to manage all your environment variables through the terminal, a VS Code extension, and a full web portal — so any team or organization can hold their variables securely. When someone leaves, you revoke their access and their reach into your production, staging, and deployment secrets disappears with them. Nothing leaks. The role-based access control was one of the most important parts of the whole thing. And it was completely broken. I'd designed a solid structure long before Fable 5 existed, but the RBAC had rotted: **partially implemented on the website, and flat-out non-existent in the CLI and the VS Code extension.** There were meant to be five roles — **Owner, Project Manager, Team Lead, Developer, Viewer** — because that's how an agile team works about 90% of the time. Each role gets access to a specific slice of the app. (One day I'll make this fully dynamic so an owner can define their own rules. For now, these are the hardcoded standard.) But the implementation had drifted: the owner role existed, the project section used one set of roles, the environment variables used a different set. A developer could touch the variables, a viewer could only read them — and none of it lined up. It was a mess I'd been avoiding for weeks, waiting for the day Fable came back to help me clear it. So the moment it did, I didn't hold back. I opened four terminals — one in T3 Code, two in Ghostty — and started working three projects at once. envpilot.dev went first. I told Fable the exact workflow and role structure I wanted and set it loose. This was in T3 Code, which is a fantastic tool. It figured out the plan, I told it to go, and it executed — then tested the whole thing end to end. I had it write Playwright tests *and* smoke tests so the app got checked properly, not by me clicking around manually. That's the part that kills me about working straight on Opus 4.8: with Opus I have to run tests by hand. Fable orchestrated it so Opus and Sonnet did the testing themselves, with Fable grading their work the whole way. A couple more prompts fixed the last rough edges — the invitation section wasn't working, and the UI had that old habit these models can't shake: dummy, boxy, ugly components built from scratch. I already have themes and components I like and a vibe I want to keep, so I told it to use *those* and stop inventing. It listened. Then I reviewed the PR, tested locally, tested on staging, and shipped it to main where everyone's now using it. It even wrote the migrations — the old system's data model was wrong, the new one was correct — and I ran the migration straight from my admin panel. It detected every user and fixed their roles cleanly. The orchestration was tight, and it didn't eat nearly as many tokens as I braced for. That was one part. The website. But envpilot lives in three places, so I wasn't done. ## Project two: the CLI and the `envpilot run` command Once I'd merged the website fix and run the migration, I told Fable the code was in main and it was time to rework the CLI — starting with the one command I live in: `envpilot run`. Here's what that command does, and why I care so much about it. Instead of your dev server pulling secrets from a local `.env` file, `envpilot run` **injects the environment variables straight into the running dev server at the right place, at the right time.** This matters more than ever in the AI era. Everybody's running AI tools now, and those tools happily read your memory and your files — including your `.env` — and keep your chat history around. That's exactly how API keys leak. `envpilot run` keeps the secrets out of any file an assistant can casually read. With thousands of projects across my org and my personal work, that command is load-bearing for me. I also told Fable to audit the code while it was in there — dead code, complexity, UI bugs, whatever it could find. It caught a few real ones: the authentication was reorganizing itself in a way that broke things, some polling logic was off, and continuous injection was doing more work than it should. My backend is mostly Convex, and I'm still on the free tier — even with all my traffic I haven't crossed it, and I'd really like to keep it that way. Fable actually reasoned about *how* the polling worked and where it was costing me, then fixed it. CLI done, in its own PR. ## Project three: the VS Code extension (plus two new features) Same playbook for the VS Code extension — another PR, same orchestrated execution — but this time I added two features I'd wanted for a while: **switching between multiple accounts, and switching between projects.** Picture it: you've got a personal account, your organization has its own account, and you're on another team too. Bouncing between two accounts or two projects is a genuine pain. Now it's one click. And here's where the difference between the models got obvious. When I read the code Opus 4.8 had written, it was *beautiful* — and messy. It'll dump a huge amount of logic into one giant file and then forget that file exists. Fable looks at that same code and asks how to break it into small modular pieces that can be optimized later. It hunts for bad smells and needlessly complex logic. My favorite tell is dependencies. Say you need a dialog box. Every Chromium browser — Chrome, Brave — and Firefox already ships perfectly good native dialogs. Opus will go install a dependency, import it, wire up its own thing, and hand you something uglier than the built-in. Fable checks what the browser already supports, finds the compatible native option, and uses the cleanest, smallest, correct one. If you actually need customization, *then* it'll tell you the default won't cut it and lay out your options. I don't know how Anthropic tuned this in, but that instinct alone fixed a real problem for me. ## Project four and five: Crisp goes to Windows Same story played out on two more of my apps. **Crisp** is a small video-editing app that detects things like language and phrases, pauses, cuts, and auto-framing to make editing easier — because for someone new who's never edited, all of that is a wall. I built it to knock that wall down. But I'd only built it for macOS: a Swift app with a Python engine under the hood. There was no Windows port anywhere. So I gave Fable the macOS version, the Python engine, and one instruction: replicate this on Windows, feature for feature, one-to-one parity. In a couple of hours it did it. It ripped the Python core engine out of the Swift app and rebuilt it as the heart of a cross-platform Windows build, with the auto-detection and triggering intact. The first UI it made was bad — but the *functionality* was there, one-shot. Then I told it Windows is a native platform and I wanted the whole UI thrown out and rebuilt with native Windows tooling. What came back — the color scheme, the vibe, the onboarding — was spot on. And then **Vitals**, my system monitor. If you've read the blog you know it: a menu-bar app for fans, RAM, temps, storage, widgets — Activity Monitor on steroids and a lot better looking. It was my very first Swift app, built with the older, code-capable version of Fable, and this session pushed it another level up. ## The honest cons So those are the wins. But there's always a fallback, right? A model this good has to have a catch, and it does. I could go on about the little behavioral quirks, but the one that actually matters is **cost.** These models are genuinely expensive — roughly **$5 per million input tokens and $15 per million output**, with a separate charge for caching on top. And none of it is in a subscription. I've seen Anthropic's DevRel say on X that there's a compute crisis going on: they *want* to put Fable in the subscription tiers, but not yet. For now it's API credits only. Maybe down the line Fable 5 becomes the default model in the subscription — and if you're paying $100 or $200 a month, honestly, it'd be worth it. There's nothing like it on the market. There's a cheaper way to play it, too. Pair a $20 or $100 OpenAI subscription with Fable: let **Codex** do the actual coding, and let **Fable 5** (or any Mythos model) do the thinking, the planning, the review, and the bug-hunting. Theo's shown this exact split on X, and from how he talks about it, I think that's the future taking shape. Two models side by side — one writes, one thinks and revises and finds what's broken. That combination is so much better than either alone. Because that's really the shift. We're at the point where **writing code isn't the hard part anymore.** Thinking outside the box, designing the system, scaling it — that's what matters now. The typing is solved. The architecture isn't. ## What's next Today's the 4th of July; this goes up on the 5th. I've got a stack of things lined up, most of it on envpilot.dev: GitHub Actions, an account-transfer option, native Android and iOS apps, and a subscription model that's almost set but needs to be bulletproof. I want to add a networking system to Vitals. I want to use Fable 5 for the Windows port of Crisp — GPU support, CUDA, AMD — plus payment and licensing on Windows, and I need to fix the in-app Windows updater, which is completely broken right now. There are so many edge cases and features I want to hit, and I'm sharing a Fable account with five or six other people, so my window is tight. But holy cow, I'm impressed. Just know this: the moment the price and the API rates settle, this will not be a cheap model. There's no way around it. So if you think you can afford it — go for it. There's nothing else like it out there. There *are* a lot of Chinese open-source models worth watching, though — like **GLM 5.2**, which I've been using extensively. Back when Fable was still pulled and GLM was all I had, I ran it hard in harnesses like OpenCode. I've got a pile of notes and a whole separate post coming on those models in a few days. Can't wait to share what I found. Until then, nerds. 👋 --- # I'd Never Built a Mac App. So I Built a Whole System Monitor. - **URL**: https://www.rafay99.com/blog/id-never-built-a-mac-app-so-i-built-a-whole-system-monitor/ - **Published**: 2026-06-15 - **Author**: Abdul Rafay - **Tags**: Swift, SwiftUI, macOS, AICoding, ClaudeCode, BuildInPublic - **Description**: One prompt, about 30 hours over two days, two AI models (one got banned mid-build), and a native macOS system monitor I now use instead of Activity Monitor. The full build story — fan-control hacks, a 17.5 GB ghost, and all the bugs in between. It started with one message. Typos and all: > "this is my mac and I need an app that can help me check the stats of my laptop — fan speed, temp of each core, average temp… a native app. I have never built an app like this. clean code, clean charts, be a part of the system and not stick out like 'oh I am an ugly app.' you have total freedom on tech." I want to be straight with you before anything else: **I had never built a Mac app in my life.** Not a small one, not a toy. Nothing. I live in Django, Next.js, Flutter. AppKit and SwiftUI were a foreign country. Two days later I had a native macOS system monitor — fan control, app management, storage analysis, desktop widgets, a marketing site, a test-gated release pipeline, an auto-updater, and a Linux port in progress. I called it **Vitals**, and I now use it instead of Activity Monitor. This is the story of how that happened — the good decisions, the dumb bugs, and the one moment where the AI model I was building with got pulled out from under me *mid-feature.* (If you read my last two posts, you already know which model.) ![Vitals dashboard](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJtMnaQH5Tkd73eKjcbxAusS1ZaL02X5lBpmzU) # The sentence that decided everything "Be a part of the system and not stick out." That one line made every big technical call for me. It's why the answer was **Swift and SwiftUI**, not Electron. Native is the only way to get the system materials, the SF Symbols, the real system fonts, and Apple's Charts framework — the stuff that makes an app look like Apple shipped it instead of like a web page in a costume. Fan speed and temperatures don't come from some tidy API either; they come from the **SMC** (the System Management Controller) and private **IOKit HID** services. Within a couple of hours, Vitals was running on my M4: live per-core die temperatures, fan RPM, CPU and memory, thermal pressure — and a little `°` readout sitting in the menu bar like it had always been there. That part was easy. Everything interesting happened after. # The first real bug: an app that ate itself The early features came fast — a native Settings window, temperature units, refresh rate, chart history, an overheat threshold. Then the app **froze the second it launched**, pinned at 100% CPU. The cause is a beautiful little SwiftUI trap. The menu-bar item's show/hide state was a two-way binding that got written on *every* scene refresh. It was bound to a published settings property, so every write triggered "settings changed" → re-render everything → write again → forever. The main thread never got a millisecond to handle a click. Which, by the way, is *also* why the Settings window looked like it wouldn't open. One bug wearing two disguises. Break the binding loop, and idle CPU dropped from 100% to about 2%. That gave me the rule that ran the entire rest of the project: **on a monitoring app, the main thread is sacred.** Everything that followed — actors, off-main sampling, deferred rendering — traces back to that first humiliation. # Shipping it like a real app, not a binary I didn't want a thing that lived in a folder. I wanted the *experience* of an app. So we built: - A **drag-to-install DMG** — mount it, see the icon with an arrow pointing at Applications, drag, done. - A **private repo with CI** — and a pleasant surprise: GitHub's macOS runners can actually build the thing, so there was a real build check from day one. - A full **release + auto-update pipeline**: push to main → CI builds, versions, packages the DMG, publishes a GitHub Release → the running app notices, downloads, installs, relaunches. Plus a manual "Check for Updates." And one small decision I'm weirdly proud of. The auto-versioner spat out `1.1.1` and I hated it. So I made a call: > the version should just *be* the number of commits. 10 commits → 0.10. So the version became the git history itself: `0.$(git rev-list --count HEAD)`. No version file, no manual bumping, no decision to ever make again. That scheme carried all the way to **v0.20** and quietly became load-bearing — you can never switch how you count commits, because the version can't go backwards or the updater breaks. # The fan-control saga (my favorite fight) Reading sensors is easy and safe. *Writing* to hardware is where you respect the machine. Fan control is the one feature that can actually cook your laptop, so it got maximum paranoia. First attempt: failed with SMC `result 130`, and worse, a password prompt **every single time I moved the slider.** I pushed back hard, because that's obviously broken, and pointed at the open-source reference everyone uses: Mac Fan Control. Reading how *they* did it cracked the whole thing open — because there were actually two separate problems hiding as one. **Problem one: the fan never spun at all.** `result 130` wasn't a permissions error — the write ran as root and *still* got rejected. The fan was reporting `F0Md = 3`, "system mode," which is the M-series firmware running its own thermal mitigation. And on Apple Silicon, the firmware flat-out **refuses a direct "switch to manual" write** unless you first flip a hidden diagnostic-unlock key called **`Ftst`**. The fix was a little dance: set `Ftst=1` to unlock → retry the mode switch → then write the target RPM as an **IEEE float** (Apple Silicon uses floats; Intel used a different format entirely). **Problem two: the password-every-time thing was an architecture flaw,** not a sensor one. The fix was a **privileged root LaunchDaemon** — a tiny separate process that runs as root, reads a state file, and applies fan settings. The GUI escalates exactly once, at install, and never bothers you again. That daemon is the one component in the whole app that *has* to be root, and it's isolated on purpose. This is also where I locked in the hardest rule in the codebase: clamp to the fan's rated RPM range, keep macOS's own thermal safety running underneath you, and never let a hardware write escape its guardrails. **Read freely, write carefully.** # The moment the model disappeared Here's the part that ties this whole thing to my last two posts. Everything up to now — every feature, every bug above — was built with **Claude Fable 5.** It was unreal to work with; I wrote a whole love letter about it. The next feature, a Storage tab, kicked off on Fable 5 too. And then, mid-task, the screen gave me this: > *"There's an issue with the selected model (claude-fable-5). It may not exist or you may not have access to it."* That was it. That was the moment, from the *inside*, of the thing I'd written about from the outside — [the US government pulling Fable 5](/blog/they-pulled-fable-5). I was halfway through a feature and the best tool I'd ever used simply evaporated under my hands. I tried to resume. Same wall. Again. Same wall. So I picked the work up on **Opus 4.8** and kept going — same branch, same half-finished Storage tab, no lost context. It just… continued. Honestly, that seam is the cleanest illustration I have of where these two models actually differ. Fable let me walk away. Opus is brilliant but wants me in the chair. From the storage feature onward, I was back in the chair — and the app still shipped. Everything from here was built on Opus. ![Vitals storage analysis](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJrwUo7OyP1w3SZ8vfyplIOCXQx5bWATscUJFN) # The jank hunt (and the bug I killed by deleting the architecture) The feature I remember most isn't a feature. It was a multi-day war against UI jank — that tiny ugly stutter when you open the window or toggle the sidebar. I chased it through five separate causes: 1. **Switching tabs re-ran everything.** The sidebar was destroying and recreating views on every switch, so every visit to the Apps tab kicked off a full disk rescan with a "Scanning…" flash. Fix: hoist the models up so scans survive tab switches. 2. **The dashboard rebuilt every card, always** — including the heavy below-the-fold charts — on every layout. Fix: lazy layout, and batch all the Liquid Glass blur into a single pass instead of N separate backdrop captures. 3. **Charts have a documented ~50–150ms first-layout hang.** Opening a window *materializes* views; closing only tears them down. That asymmetry was the clue. Fix: animate against placeholders, fade the charts in a beat later. 4. **Adaptive grids reflow mid-animation.** I recorded my screen, pulled the frames apart with `ffmpeg`, and watched the die-temperature map snap from 8 → 9 → 6 columns *during* the sidebar animation. Cause: an adaptive grid. Fix: fixed column counts. 5. **The real villain was the window chrome.** Even after all of that, a small window still jerked on open. The culprit was the toolbar — AppKit *snaps* the toolbar and title into place (it doesn't animate them) when the sidebar re-anchors. There's no setting to fix that. You can't optimize it away. So I made the call that I think is the single best decision in the project: **kill the things that snap.** I dropped the standard split-view navigation entirely and rebuilt the whole shell as a stationary header with capsule tabs — Activity Monitor style. No system title bar, no toolbar, no sidebar. The entire *class* of bug died by construction, not by tuning. The rule it left behind: **window geometry must never change from navigation.** That's the lesson I keep relearning. Sometimes you don't fix the bug. You delete the thing that makes the bug possible. # Three more war stories, fast There were too many to tell all of them, but these three earned their place: **The AlDente standoff.** Testing the uninstaller, I told it to remove exactly one app — AlDente, nothing else. The confirmation correctly listed only AlDente. I confirmed. Result: *"Moved 0 items. 1 couldn't be removed."* It hadn't worked — but crucially, *nothing else got touched.* The diagnosis was sharp: AlDente was installed as root, and macOS **App Management** protection won't let an ad-hoc-signed app move another developer's app. The fix routed protected bundles through the same single admin prompt the rest of the cleanup used. And the part I respect most: when the UI automation got flaky near a destructive click and risked selecting the wrong app, the right move was to **stop**, not gamble. Write carefully means write carefully. **The 17.5 GB ghost.** Someone ran Vitals in a VM and it ballooned to 17.5 GB and went "Not Responding." Panic. But on real hardware it sat flat at ~135 MB forever, so it wasn't a leak. The mechanism was the **GPU** — a VM has none, so SwiftUI renders in software, and Liquid Glass (live backdrop blur) plus constantly-animating charts balloon offscreen buffers when there's no GPU to lean on. Fix: detect a real GPU and only enable the fancy glass when one exists. Zero change on real Macs. That scare also triggered a full robustness audit — watchdogs, bounded buffers, a battery reader that reports *unknown* instead of inventing 0%. **Widgets that don't use WidgetKit.** I wanted desktop widgets, but real WidgetKit was a dead end for this app (a macOS 26 loading bug, plus data-sharing needs a paid Team ID the ad-hoc build doesn't have). So instead the app spawns its own floating desktop panels, bound to the *same* live data the app already polls — real-time, no extension, no new permissions. Getting them to sit on the true desktop layer and not flicker during a Space switch was its own little obsession. The honest limitation, which I stated plainly: these can never show up in Apple's official widget gallery. That surface only lists real extensions. No clever hack changes it. ![Vitals desktop widgets](https://7huqjqx8yo.ufs.sh/f/TViMykBJnLIJUjZGtzxZdb0IOL1s3KJqktcxwpW9faXP2muE) # The four principles that actually carried it Strip away the features and the bugs, and the whole thing ran on four ideas that kept paying for themselves: **Don't stick out.** Native materials, system fonts, the platform's own idioms. The biggest architecture decision in the project — killing the sidebar — came from refusing to accept chrome that didn't move the way Apple's does. **Honesty over decoration.** A fan at 0 RPM *says* 0. A storage category that got cancelled mid-scan reads "Not measured," never "Empty." The battery reports *unknown* rather than a fake 0%. And the day I added crash diagnostics, the privacy policy got rewritten in the same change, because it used to promise "no telemetry" and shipping otherwise would've been a lie. The numbers an honest monitor shows you have to be *real*, or the whole app is pointless. **Read freely, write carefully.** Reading sensors is liberal. Every single thing that writes — fan control, deep cleanup, system-level uninstall — got confirmation, re-validation, and reversibility where possible. When automation got shaky near something destructive, stopping was the correct engineering. **Layers that don't leak.** Services know hardware, not UI. Models poll and publish off the main thread. Views only ever display. That clean separation is the *only* reason the performance fixes were even possible. And the quietest lesson, the one under all the others: the best debugging in the whole project — the `Ftst` fan unlock, the App Management standoff, the toolbar snap, the GPU-less VM blow-up — never came from guessing. It came from reading the reference, measuring the real hardware, pulling apart the actual video frames. Then fixing the *actual* cause. # Where it is now — and it's yours too By the end of that two-day sprint, Vitals was around v0.20: a native macOS monitor with fan control, app management and cleanup, storage analysis, desktop widgets, opt-in crash diagnostics, an auto-updater, a marketing site, a test-gated release pipeline, and a read-only Linux port (Rust + GTK4) in progress. It hasn't stopped since — as I write this it's on **v0.26**, because the version is still just the commit count and the commits keep coming. Here's the part I didn't plan on when I started: **I open-sourced the whole thing.** The Swift app and the website live in one public monorepo under the **GPL-3.0** license. Free, Apple Silicon only, no account, no catch. - 🔗 **Site & download:** [vitals.rafay99.com](https://vitals.rafay99.com/) - ⬇️ **Direct DMG:** [grab the latest release](https://github.com/rafay99-epic/Vitals/releases/latest/download/Vitals.dmg) — requires macOS 15 or later, Apple Silicon - 💻 **Source:** [github.com/rafay99-epic/Vitals](https://github.com/rafay99-epic/Vitals) A word on the boring-but-important stuff, because "honesty over decoration" applies to more than charts. Vitals is **privacy-respecting by default**: no usage tracking, no analytics on what you do, nothing quietly phoning home about your machine. The only telemetry is **opt-in crash and performance diagnostics that stay off until you switch them on** — and the day I added even that, I rewrote the [privacy policy](https://vitals.rafay99.com/privacy) so it matched reality instead of promising something it no longer did. The [terms](https://vitals.rafay99.com/terms) and the full GPL license sit right there in the open. Read them, fork it, tear it apart — that's the whole point. The credit is in the open too: the cleanup engine is informed by **[Mole](https://github.com/tw93/mole)** (also GPL-3.0), and the SMC fan-control breakthrough came from studying **Mac Fan Control**. No code copied from either — but their work unlocked mine, and they're named in the README, the source, the site, and the app's About screen. It was built across two days, two models, and one stubborn refusal to let it "stick out." I built a thing I genuinely use, in a language and a platform I'd never touched, by treating the model like a very fast junior engineer who needed a real architect making the calls — which is to say, by staying in the chair and arguing with it when it was wrong. The version is just the commit count. It's climbing. More soon. If you want the build details on any one of these fights — the fan daemon, the desktop-layer widgets, the test gating — tell me and I'll do a deep-dive post on it. Stay sharp out there. 👋 --- # They pulled fable 5 - **URL**: https://www.rafay99.com/blog/they-pulled-fable-5/ - **Published**: 2026-06-14 - **Author**: Abdul Rafay - **Tags**: AI, ClaudeFable5, Anthropic, AIPolicy, ExportControls, ThoughtsProcess - **Description**: Two days after I wrote a love letter to Claude Fable 5, the US government forced Anthropic to shut it off. Here's what actually happened, why it happened, what it means for developers outside the US, and what Anthropic does next. Two days ago I published a love letter to Claude Fable 5. I told you it was the best model I'd ever used, that I gave it one prompt and walked away and came back to a whole working game, that it shipped real features into my production app while I was *writing the post about it.* I meant every word. Today it's gone. Not deprecated. Not rate-limited. Not "moved to a higher tier." **Pulled** — by the United States government. On Friday, June 12, the Commerce Department handed Anthropic an Let me walk you through what happened, because the details are wilder than the headline — and one of them hit me personally in a way I didn't expect. # What actually happened Friday evening, 5:21pm Eastern, Anthropic received a letter. It came from the Commerce Department — the directive itself signed out by Commerce Secretary Howard Lutnick — citing national security authorities. The instruction: suspend all access to Fable 5 and Mythos 5 for **any foreign national**, whether they're inside the United States or outside it. That includes Anthropic's own non-citizen employees. Here's the catch that turned a targeted order into a global blackout. Anthropic can't cleanly fence off "only foreign nationals" from a live consumer product used by hundreds of millions of people. So to comply, they had to pull the plug for **everyone** — Americans included. Their other models (Opus 4.8, Sonnet, Haiku) are untouched and working normally. Only the new Mythos-class tier went dark. As far as anyone can tell, this is the **first time a leading AI company has been forced to take a publicly deployed model offline because of a federal order.** That's the part that should make you sit up. Not a recall of a beta. Not a voluntary pause. A shipped, paid, in-production frontier model, switched off by government directive, overnight. And the letter, by Anthropic's account, didn't even spell out the specific national security concern. # The part that made me close my laptop for a second So why did they do it? Anthropic's read is that the government believes someone found a way to "jailbreak" Fable 5 — to slip past the safeguards that normally keep its heavy cybersecurity capabilities locked down. And here is the detail that stopped me cold. According to Anthropic, the only evidence handed over so far was *verbal*, and the jailbreak in question essentially amounts to this: **asking the model to read a specific codebase and fix any software flaws it finds.** Read that again. Then go read my last post. That is *exactly* what I spent two thousand words praising. Point Fable at a repo, let it read the whole thing, let it find what's broken and fix it. I watched it do that to my own app, Wryte — read the codebase, add rate limits I didn't ask for, wire up cleanup logic in every place a new table needed it. I called it the senior engineer who finally lets you walk away. The government is calling that same behavior a national security weapon. I don't say that to be glib. I genuinely don't know where the line sits between "reads your code and patches your bugs" and "reads anyone's code and finds the holes." They might be the same muscle pointed in two directions. But it's a strange thing to watch the exact capability that made the tool feel magical get reclassified, within 48 hours, as the reason it's too dangerous to exist in public. And there's a more personal sting. I'm a foreign national. I'm writing this from Pakistan. The order is, by its own plain text, about people like me — *any foreign national, inside or outside the United States.* For two days I was holding the absolute frontier of this technology in a terminal on my desk. Then a letter went out in Washington that had my entire category's name on it, and the frontier closed. # Anthropic's side of it To their credit, Anthropic didn't go quiet. They published a sharp, unusually direct statement, and their argument is worth laying out fairly. Their position, in short: the jailbreak the government is worried about is **narrow, not universal.** A universal jailbreak would crack the safeguards wide open across the board — and Anthropic says nobody, in thousands of hours of red-teaming with the US government, the UK's AI Safety Institute, outside firms, and internal teams, has found one. What's been disclosed to them are either harmless outputs or minor findings that give no real Mythos-specific advantage. They say they haven't received a single disclosure of a concerning jailbreak that actually led to a harmful result. Their sharpest point is a comparison: the same "read a codebase, find the flaws" capability, they say, is **already available from other public models** — they name OpenAI's GPT-5.5 specifically — none of which are under this kind of They're complying. But they called the whole thing a misunderstanding, and they issued a warning that's bigger than their own product: if "a narrow potential jailbreak justifies recalling a model used by hundreds of millions" becomes the standard, it would freeze new model launches across the *entire* industry, for everyone. Their stated view is that the government *should* be able to block genuinely unsafe deployments — but through a process that's transparent, fair, and grounded in technical facts, and they don't think this one was. # The deeper analysis: why *this* model, why *now* This is where it gets uncomfortable, because the timing and the target don't look random — and the honest answer is that there are several competing explanations, and the truth is probably a blend of them. Let me give you the lenses, not a verdict. **Lens one: this is the latest shot in an existing war.** This didn't come out of nowhere. Back in February, the Trump administration ordered federal agencies to stop using Anthropic's models after the company refused the Pentagon's preferred contract language — terms that would have let purchased models be used "for any lawful purpose." Anthropic wanted carve-outs against things like autonomous weapons and mass domestic surveillance. In March, the Pentagon branded Anthropic a "supply chain risk," and the company is now fighting that designation in federal court. Senior administration tech voices like David Sacks have publicly gone after Anthropic, accusing it of regulatory capture and worse. Through this lens, the **Lens two: Anthropic wrote this script itself.** This is the most uncomfortable read, and I think it's the most underrated one. For over a year, Anthropic's entire brand has been *"our models are so powerful they're dangerous, and only we can be trusted to handle them safely."* They described Mythos as too dangerous to release. They wrapped Fable in safeguards and made a whole marketing story out of how locked-down it was. A cybersecurity researcher named Peter Girnus put it brutally: Anthropic spent months describing its own product as essentially a weapon, so eventually the government simply believed them. As he put it, "they wrote the legal predicate themselves and called it a brand." You cannot spend a year telling the state your tool is a munition and then act shocked when the state regulates it like one. **Lens three: it's genuine, if clumsy, national-security caution.** It's also possible the government simply got spooked by a live demonstration, acted fast and broad because that's what national-security machinery does, and the lack of detail in the letter reflects classification rather than malice. AI critic Gary Marcus argued the move actually makes sense if you take the "stay ahead of China" doctrine seriously. You don't have to like the execution to grant that the underlying worry — frontier cyber capability leaking to adversaries — is not imaginary. **Lens four: some people quietly wanted this.** Here's the twist Dean Ball floated. There's a wing of the AI world that genuinely believes these systems pose serious, even existential risk, and that the whole industry is moving too fast. For them, a government slamming the brakes on the most powerful public model isn't a disaster — it's a win. That faction may well include some of the safety-minded people *inside* Anthropic. So the reaction to this isn't cleanly "everyone is furious." It's messier than that. My honest take, for whatever a developer in Rawalpindi's opinion is worth: it's lenses one and two together. There's a real feud, and Anthropic handed the other side a loaded gun by branding its own product as ammunition. The security rationale is the wrapper; the politics are the engine. # What I think happens next (predictions) Nobody knows. But patterns exist, so here's where I'd put my chips. 1. **Short term, Anthropic fights and the model probably comes back — partially.** They promised more evidence within 24 hours, they're calling it a misunderstanding, and the login page says *temporarily* unavailable. All of that is the language of a company that expects to win an appeal, not one that's accepted a death. I'd bet on Fable returning in some form within weeks — but possibly region-locked, US-persons-gated, or with even heavier restrictions. Which, for most of the planet, is its own kind of loss. 2. **The "foreign national" scope is the real bomb, and it'll outlive this one model.** If the precedent holds — that America's best models can be made US-citizens-only by directive — the global developer market fractures. The frontier tier becomes something the rest of us read about but can't touch. For someone like me, that's not a temporary outage; it's a preview of a two-speed world. 3. **The competition is the immediate winner.** Every international developer who built a workflow on Fable this week just got pushed toward models that *aren't* under these controls — GPT-5.5 and whatever else. Anthropic's own argument ("the same capability is everywhere else") is true, and it cuts against them commercially. If you're a non-US team, the safe procurement choice just got more obvious, and it isn't Anthropic. 4. **A chilling effect on safety honesty.** Here's the perverse part. The lesson other labs will take from this is *don't loudly advertise how dangerous your model is, or you'll paint a target on it.* That pushes the industry toward **less** transparency about capabilities and risks, not more — the opposite of what anyone sane wants. 5. **Talent and capital get jumpy.** Marcus's point stands: capricious, hard-to-predict policy makes investors and researchers nervous about building their lives and money around US AI labs. Expect quiet hedging. 6. **The capability doesn't actually go anywhere.** History is not kind to attempts to export-control software and knowledge — the 1990s crypto wars are the textbook example, and encryption won. The ability to point a model at code and find flaws now exists in multiple systems. You can pull Fable off the shelf; you can't pull the capability out of the world. # What Anthropic actually does now Strip away the drama and their playbook is fairly clear — comply and contest, at the same time. They'll **comply** (already done — models are off) while **contesting** hard: publish the technical evidence, argue the GPT-5.5 parity point relentlessly, and fold this into the legal fight they're already running against the "supply chain risk" label. Expect a push for a real statutory process — clear rules for when the government can pull a model — because "a letter at 5:21pm with no specifics" is exactly the arbitrariness they want to litigate against. Commercially, they'll **lean on Opus 4.8 as the public face** and reassure enterprise and government customers that the workhorse models are untouched. Mythos-class becomes the thing they fight to bring back rather than the thing they sell this quarter. And strategically, they're in a genuine bind of their own making: the "safety-first, our models are dangerous" identity that won them credibility with regulators is the same identity now being used to take their product away. Watch whether they recalibrate that message — whether the next launch is described with a lot less "munition" energy. I'd bet it is. The thing they *can't* easily do is the thing that would help most — prove a negative. "Our safeguards are good enough" is an almost impossible case to win against a national-security argument, because the other side only has to gesture at a worst case. That asymmetry is the whole problem, and it's why I think this fight is going to be long. # Where this leaves me I got 48 hours. In those 48 hours I built two games I'm proud of, shipped real features into an app I actually run, and felt — for the first time — what it's like to genuinely hand a machine the whole task and trust the result. Then a letter went out in Washington and that machine switched off, and the letter was, in plain language, about people like me. I'm not going to pretend I have a clean feeling about it. Part of me thinks the government overreached on thin evidence in the middle of a grudge. Part of me thinks Anthropic spent a year describing its product as a weapon and is now shocked the state took the description literally. Both can be true. They probably are. What I keep coming back to is smaller and quieter than the policy fight. For two days, the absolute frontier of this technology sat in a terminal on my desk, in Rawalpindi, and it worked. The capability is real. It already exists. And the actual story now isn't whether Fable 5 comes back next week — it's the question this whole mess just dragged into the open: **who gets to hold the frontier, and who gets to decide that for everyone else.** I'll be back on Opus 4.8 in the morning. It's still great. It's still the one that needs me in the chair. And for now, that's the deal. I'll keep you posted as this develops — and if Fable comes back, you'll hear about it here first. Untill then Nerd.. See you Next Time. 👋 --- ## Sources - Anthropic — [Statement on the US government directive to suspend access to Fable 5 and Mythos 5](https://www.anthropic.com/news/fable-mythos-access) - Anthropic — [Original Fable 5 / Mythos 5 launch post](https://www.anthropic.com/news/claude-fable-5-mythos-5) - CNBC — [Anthropic disables access to Fable 5 and Mythos 5 to comply with government directive](https://www.cnbc.com/2026/06/12/anthropic-disables-access-to-fable-5-and-mythos-5-to-comply-with-government-directive.html) - NBC News — [Anthropic suspends new AI models after government directive](https://www.nbcnews.com/tech/tech-news/anthropic-suspends-new-ai-models-fable-mythos-government-directive-rcna349901) - Fortune (Jeremy Kahn) — [Anthropic disables Fable and Mythos after US bars foreign access](https://fortune.com/2026/06/13/anthropic-disables-fable-mythos-export-controls-national-security-threat/) - TechCrunch — [Anthropic's safety warnings may have just backfired](https://techcrunch.com/2026/06/12/anthropics-safety-warnings-may-have-just-backfired-the-government-has-pulled-the-plug-on-its-most-powerful-ai/) *This post reflects my own reading of a fast-moving story and includes informed speculation, clearly marked as such. Facts are sourced above; the predictions are mine, and I reserve the right to be wrong about them.* --- # Claude Fable 5 Built Two 3D Games From One Prompt — Full Review & Test - **URL**: https://www.rafay99.com/blog/claude-fable-5-i-gave-it-one-prompt-and-walked-away-it-built-a-whole-game/ - **Published**: 2026-06-13 - **Author**: Abdul Rafay - **Tags**: Claude Fable 5, Claude Fable 5 review, Anthropic Mythos, Claude Code, AI game development, Fable 5 vs Opus, vibe coding, Three.js game AI - **Description**: I gave Anthropic's Claude Fable 5 (Mythos-class model) one prompt and walked away. It built two full 3D browser games with Three.js. Here's my honest review — what worked, what didn't, and how to try it yourself. I want to tell you about the moment I stopped trusting my own eyes. I'd seen the Twitter hype. You probably saw it too — for two days straight, my whole feed was people throwing one prompt at Claude Fable 5 and getting back things that should not exist yet. Whole apps. Whole games. One shot. No back-and-forth. I scrolled past a dozen of these thinking *okay, cherry-picked demos, sure.* We've all watched a hundred "AI built my startup in 5 minutes" clips that fall apart the second you click anything. But I pay for the $200 Max plan. The thing is right there. So I figured — fine. Let me try to break it. I could not break it. That's the whole post. But let me actually show you. # The empty folder test One thing up front, since it matters for the whole post: I did all of this — both games and the real client work — through the **Claude Code CLI**, straight from the terminal. No fancy setup. Just me, a shell, and the model. Here's the cleanest test I know for a coding model: open the Claude Code CLI, point it at a completely empty folder, give it one prompt, and walk away. No scaffolding. No "let me set up the project structure first." Nothing for it to lean on. Just an empty room and an idea. So I did exactly that. Empty folder. One prompt describing a browser space game. And then — this is the part I want you to sit with — **I left.** I made tea. I answered some messages. I did not babysit a single token. About an hour later I came back, ran the dev server, and **Nebula Strike** was just… there. Loaded. Playable. Not a grey box with a triangle in it — a proper sci-fi space game running on Three.js, with ships, enemies, weapons, and *landable planets that have real gravity.* Fly too close to the Jupiter-class world and your main engine literally can't pull you back out until you hit the afterburner. I did not ask for that level of detail. It just decided that was the bar. And it didn't crash. It ran first try. So I did it again. And again. Different game each time, same workflow — empty folder, one prompt, walk away. Every single one launched and worked. Not "worked after I fixed three import errors." Worked. The second one became **Metropolis City Simulator** — a SimCity-style 3D city builder where you paint roads, towns grow into cities, and traffic *emerges* from your street layout. Cars actually pathfind across the network and the roads tint red as they get congested. Nobody scripted that traffic. It falls out of the simulation. I'll be honest with you. I've built games before. I know how much glue, how many tiny broken states, how many "why is this undefined" moments sit between an idea and a thing that runs. To watch that gap just… close, while I was in another room — that messed with my head a little. # Then I took it to real work Toys are fun. But a model isn't real to me until it survives my actual job. I had a revision sitting in a client project. The kind of thing where the requirements live in a PDF and translating that PDF into code is half the work. Normally that's an afternoon of reading, mapping, and carefully threading changes through an existing codebase without breaking what's already there. I pointed Fable 5 at the project, handed it the PDF, and said go. And then I did the thing again. I left. When I came back, the revision was done. Not "started." Not "here's a plan, want me to continue?" **Done.** And here's the part that actually matters more than the speed: It was correct. That's the line. Anyone can generate a lot of code fast. Generating a lot of *correct* code, against a real codebase, from a spec it had to read and interpret itself — that's a different thing entirely. # Why this feels different from Opus People are going to say "Opus 4.8 can one-shot stuff too," and they're right. It can. I use Opus every day and it's a beast. But there's a tax with Opus that we've all just quietly accepted. You steer. You monitor. You sit there and watch the stream, ready to jump in when it drifts, course-correct when it misreads the goal, nudge it back when it goes down a wrong path. The output is great — but *you are part of the loop.* You can't really walk away. With Fable 5, I didn't steer. I gave the prompt and I left the room. Twice. And both times the work was finished and right when I got back. That's not "a bit better." That's a different category of tool. Opus is a brilliant pair programmer who needs you in the chair. Fable 5 is the first one I've used that I could actually hand the whole thing to and trust the result. Anthropic's own numbers back this up — they say **the longer and more complex the task, the bigger Fable's lead gets.** That tracks perfectly with what I felt. The short stuff, everything's good at now. It's the long, multi-step, "don't lose the plot for an hour" work where this thing pulls away. # It codes like a senior, not an intern Okay — this is the part I actually want other developers to hear. The "it built a game" stuff is flashy, but *this* is the thing that changes my job. Fable 5 writes code like a good employee. Not a good *intern* — a good *employee.* Here's what I mean. A bad employee (and honestly, most AI models until now) drops into your codebase and just starts typing. Big clever solution that technically works, ignores how the rest of the app is built, reinvents three things you already had, and hands you a 600-line diff you now have to babysit. A good employee opens the repo and *reads* first. Looks at how the project is structured. Checks what tests exist. Figures out the convention you're already using — and then does the smallest correct thing that fits. They know what to touch, and just as importantly, **what not to touch.** That second one is the whole game. Fable 5 doesn't barge through your codebase writing long, bad solutions. It scopes the change, finds the right files, leaves everything else alone, and matches your existing patterns instead of bulldozing them. And here's the kicker — **I stopped doing the prompt ritual.** You know the one. "Act like a senior engineer. This app will have 5,000 concurrent users. Think about scale. Write production-quality code. Don't over-engineer." All that babysitting boilerplate we've trained ourselves to paste at the top of every prompt? Gone. I don't write any of it anymore. Fable 5 just defaults to that bar on its own. The bullshit tax is gone. ## It checks its own work This one genuinely surprised me. While it was building Nebula Strike, I watched it spin up **Puppeteer and drive the game in headless Chrome** to actually see the output — does it boot without console errors, does the ship move, does a weapon deal damage, does the wave progress. It wasn't *guessing* whether the code worked. It was running it, looking at the result, and fixing what broke. On its own. (That test harness is sitting in the repo right now if you want to see it.) For real work, that means I'm not the QA loop anymore. It writes, runs the tests, runs the build, verifies — and *then* tells me it's done. My job shrinks to confirming what it touched and what it left alone. ## Proof from a real app, not a toy The games are greenfield — fun, but easy mode. The harder test is an existing production app, so here's my actual one: [Wryte](https://wryte.xyz/), my writing app. I've been having Fable 5 add real, necessary features to it. And when I asked what the app was *missing*, it didn't hand me a wishlist of shiny nonsense. It looked at what was actually there and named the unglamorous things that would genuinely make the app better. Every time I asked Opus that same question, I got the fancy, over-ambitious "let's add AI agents and real-time multiplayer" answer that sounds great and helps nobody. Fable 5 just told me the truth about my own app. Two commits from *while I was literally writing this post*: - 🎬 [Video embeds in the editor (v0.16.0)](https://github.com/rafay99-epic/wryte.xyz/commit/b1c241e04ad66b50ef24f535410626e4bc0587aa) — and look at *how* it did it. It didn't just slam a `