↓ Skip to main content

Code Factories: The World of Warcraft Perspective

I create a character, spawn in a starting zone with a rusty sword and a vague quest to kill boars.

That’s World of Warcraft. It’s also my first day as a software developer.

In World of Warcraft, I choose a race and a class, then spend hundreds of hours leveling through zones, running dungeons, completing quests, and eventually organizing twenty-five people to coordinate a raid boss fight where one mistake kills everyone. The game is about progression, from nothing to something, from solo to coordinated, from chaos to precision.

Software development follows the same arc. The question is what level my team is playing at.

Leveling: Developer Growth
#

In WoW, every character starts at level 1. I have two abilities, no gear, and no idea what I’m doing. I kill wolves for experience. I die to enemies I’ll later defeat in one hit. I slowly unlock new abilities, talent points, and gear slots.

The leveling process isn’t a tutorial: it’s the actual game. Every level teaches me something about my class. By the time I reach the level cap, I’ve internalized dozens of mechanics through repetition.

Developer onboarding is leveling.

Junior developers start with two abilities: write code and Google errors. They fix simple bugs. They write basic functions. They die to merge conflicts they’ll later resolve in seconds.

Each project, each codebase, each production incident is experience points. Nobody becomes a senior developer by reading about architecture. People become senior developers by leveling through enough bad architectures to recognize a good one.

The WoW lesson: there are no shortcuts to the level cap. Boosted characters (players who pay to skip leveling) arrive at max level without understanding their class. Developers who skip fundamentals (jumping straight into frameworks without understanding the language, or into architecture without understanding systems) are boosted characters. They have the gear but not the skill.

Talent Trees: Specialization
#

At level 10, WoW lets me choose a specialization. A Paladin can be a tank, a healer, or a damage dealer. A Mage can specialize in fire, frost, or arcane. Each talent tree changes how the class plays entirely.

Career specialization is the same.

The backend talent tree: databases, distributed systems, API design, performance optimization. The frontend talent tree: UI components, state management, accessibility, rendering performance. The DevOps talent tree: CI/CD, container orchestration, monitoring, infrastructure as code.

In WoW, I can respec: pay gold, reset my talent points, and pick a new tree. In software, I can respec too. A backend developer can learn frontend. A frontend developer can learn DevOps. The cost isn’t gold: it’s time.

But WoW teaches something important about talent trees: depth beats breadth early on.

A player who spreads talent points across all three trees is weaker than one who commits to one. A developer who tries to master everything is weaker than one who goes deep on one domain first, then branches out later.

Specialize. Then generalize.

Questing: Tickets and Tasks
#

Quests in WoW are simple: accept task, complete objective, turn in for reward.

Kill ten wolves. Collect fifteen herbs. Escort an NPC across a danger zone. The objectives are clear. The rewards are predictable. The difficulty scales with level.

Tickets are quests.

A Jira ticket says: implement this feature, fix this bug, refactor this module. The objective is clear, or it should be. The reward is a shipped product.

But WoW also teaches that not all quests are worth doing.

Some quests send players across the map for minimal experience. Some quest chains look tedious but unlock a dungeon. The experienced player knows which quests to skip and which to prioritize.

The experienced developer knows the same thing. Not every ticket deserves the same investment. Some are quick wins with high impact. Some consume days for negligible value. The skill isn’t in completing the quest: it’s in choosing the right quests.

Dungeons: Sprint Delivery
#

At level 15, I enter my first dungeon.

Five players. One tank. One healer. Three damage dealers. A dungeon is a structured challenge that cannot be completed alone. I need a group, each performing their role, communicating through pulls and boss fights.

Dungeons are sprints.

A small team, a defined scope, a clear objective, a fixed timeframe. The tank sets the pace, pulling groups of enemies, controlling the flow. The healer keeps everyone alive, handling the unexpected, patching mistakes. The damage dealers execute, killing targets, following priority, managing resources.

A sprint works the same way.

The tech lead is the tank: they scope the work, set priorities, manage risk. The more senior developers are the healers: they catch issues in review, patch architectural problems, keep the codebase healthy. The team executes, writing features, fixing bugs, shipping code.

WoW teaches a critical dungeon lesson: the group moves at the pace of its weakest coordinated member.

One player who doesn’t know the strategy, doesn’t listen to the leader, or attacks the wrong target can wipe the group (get everyone killed). In a sprint, one developer who misunderstands the requirement, skips code review, or deploys without testing can derail the whole release.

Communication isn’t optional. It’s the difference between a smooth run and a wipe.

Raids: Large-Scale Projects
#

Raids are WoW’s endgame content.

Ten, twenty, or forty players coordinating to defeat bosses with complex mechanics. One person stands in the wrong spot and the entire raid dies. One healer misses a healing rotation and the tank falls. One damage dealer ignores a mechanic and the boss enrages.

Raids are large-scale projects.

Multiple teams coordinating across a shared objective. One service goes down and the whole product suffers. One team misses their deadline and the launch slips. One undocumented dependency surfaces and everything breaks.

The raid leader is the engineering manager.

They don’t play the game for the team: they coordinate. They call out mechanics before they happen. They adjust the strategy when something goes wrong. They decide who sits out when the group is too large.

Good raid leaders don’t micromanage individual players. They trust each player to execute their role while they focus on the overall plan. Good engineering managers do the same: they set direction, remove blockers, and let engineers engineer.

WoW raids also teach preparation.

I don’t walk into a raid unprepared. I bring flasks, food buffs, enchanted gear, and consumables. I’ve studied the boss mechanics on forums and in videos. I’ve done the prerequisite attunement quests.

Large projects require the same preparation. I don’t walk into a rewrite without understanding the current system. I don’t migrate a database without load testing. I don’t launch a product without a rollback plan.

Underprepared raids wipe. Underprepared projects fail.

Tank, Healer, DPS: Team Roles
#

WoW’s holy trinity (tank, healer, damage dealer) is the foundation of every group activity.

The tank takes the hits. They stand in front of the boss, absorb damage, and keep threat so nobody else gets attacked. Without a tank, the group dies instantly.

The healer keeps everyone alive. They undo damage, cleanse debuffs, and resurrect the dead. Without a healer, the tank dies and the group follows.

The damage dealers kill the boss. They do the actual work of reducing the boss’s health to zero. Without damage dealers, the encounter never ends.

Engineering teams have the same trinity.

The incident responder is the tank: they take the hits when production goes down. They absorb the pressure, communicate with stakeholders, and keep the problem focused so others can work.

The code reviewer is the healer: they catch bugs before they ship, suggest improvements, and mentor through feedback. They keep the codebase healthy.

The feature developer is the damage dealer: they write the code that ships the product. They push the project forward, sprint after sprint.

Every role is essential. Every role is underappreciated by the other roles. Damage dealers complain about long queue times because there aren’t enough tanks and healers. Tanks and healers complain that damage dealers are replaceable.

In software, everyone has complained about both sides. Feature developers complain that code review is slow. Code reviewers complain that features are rushed. The truth is the same as in WoW: a team needs all three, and disrespecting any role is how the team wipes.

Gear and Item Level: Tools and Experience
#

In WoW, gear matters. A level 60 character in quest greens (common-quality gear from quests) loses to a level 55 character in raid epics (rare-quality gear from raids). Item level (the numerical representation of gear quality) determines whether I’m invited to groups, accepted into raids, or competitive in PvP.

But gear is a multiplier, not a substitute.

A player in the best gear who doesn’t know their rotation (the optimal sequence of abilities) does less damage than a skilled player in mediocre gear. The game rewards both (players need skill to earn gear, and gear amplifies skill) but skill is the foundation.

Developer tools and experience are gear.

A senior engineer with modern tooling (AI-assisted IDEs, comprehensive test frameworks, powerful debuggers) ships faster than one without. But a senior engineer with bad tools still outperforms a junior engineer with the best tools.

The mistake teams make is treating tools like gear drops (equip them and instantly get stronger).

Tools don’t work that way. Neither does gear.

In WoW, I earn gear through repeated runs, understanding mechanics, and gradual improvement. In software, I earn proficiency with tools through repeated use, understanding trade-offs, and gradual improvement.

Buying the most expensive IDE doesn’t make anyone a better developer. Equipping raid gear doesn’t make anyone a better player. Using the gear effectively does.

Boss Mechanics: Complex Bugs
#

Every raid boss in WoW has mechanics.

Don’t stand in the fire. Switch targets when extra enemies spawn. Spread out during the explosion. Stack up during the healing phase. Each mechanic is a rule. Break a rule and the group takes damage. Break enough rules and the group wipes.

Complex bugs have mechanics too.

The race condition only triggers under concurrent load. The memory leak only appears after 48 hours of uptime. The null pointer only occurs when the user has an empty cart and clicks checkout twice. Each condition is a rule. Satisfy the right combination and the bug reproduces.

WoW teaches a specific approach to boss mechanics: learn the fight, don’t brute-force it.

I don’t defeat a boss by throwing myself at it repeatedly, hoping for better luck. I study the mechanics, adjust my strategy, and execute precisely. A boss that takes 50 wipes to learn might die in a single attempt the next week with the right approach.

Debugging complex bugs is the same.

I don’t fix a bug by randomly changing code until it works. I read the logs, reproduce the issue, identify the conditions, and fix the root cause. A bug that takes a week to diagnose might be fixed in one line once I understand the mechanic.

The raid strategy for new bosses: watch a guide, learn the phases, practice the execution. The debugging strategy for new bugs: read the stack trace, identify the phase, fix the condition.

Wipe Recovery: Incident Response
#

In WoW, a wipe means everyone dies.

The boss resets. The group runs back. The resurrection timer ticks. I repair my damaged gear, rebuff, and try again.

What separates good raid groups from bad ones isn’t whether they wipe; everyone wipes. What separates them is how they recover.

Bad groups rage in voice chat. They blame the healer, the tank, the damage dealers. They argue about whose fault it was while the respawn timer counts down. They waste five minutes on blame before trying again. And they wipe again, because they didn’t learn anything.

Good groups skip the blame. Someone calls out what went wrong (“the healer got silenced during the area-of-effect phase”) and the group adjusts. They try again in thirty seconds. They might wipe again, but they wipe to a different mechanic, which means they’re learning.

Incident response is wipe recovery.

A production outage is a wipe. Something broke. Users are affected. The system needs to recover.

Bad incident responses are blame-heavy. “Who deployed this?” “Why wasn’t this tested?” “Who approved this change?” The questions are valid but the timing is wrong. The team is still in combat. Fix the issue first. Do the post-mortem later.

Good incident responses are diagnostic. “What changed?” “What’s the error rate?” “When did it start?” The group focuses on understanding and fixing, not assigning fault. The post-mortem comes after the system is healthy (in WoW terms, after the boss is dead).

The WoW lesson: wipe, learn, adjust, try again. The speed of iteration determines the speed of progression.

Guilds: Engineering Organizations
#

In WoW, guilds are persistent groups of players who raid together, share resources, and build social bonds.

A good guild has clear leadership, a shared culture, and mutual respect. Players show up on time, prepared, and committed to the group’s success. They help each other gear up. They share strategies. They celebrate kills together.

A bad guild has drama. Loot disputes. Attendance problems. Players who show up unprepared, demand carries, and leave when they get what they want.

Engineering organizations are guilds.

The good ones have clear technical direction, a culture of code review, and mutual respect between teams. Engineers share knowledge, mentor juniors, and celebrate launches. They invest in shared infrastructure that benefits everyone.

The bad ones have politics. Turf wars over services. Engineers who hoard knowledge and resist review. Teams that optimize for their own metrics at the expense of the product.

WoW players know: the guild determines the experience more than the game.

A great guild makes mediocre content fun. A bad guild makes great content miserable. The same is true in software. A great team makes a boring product interesting. A toxic team makes an exciting product unbearable.

Choose the guild carefully. Or in hiring terms: choose the team carefully.

The Auction House: Package Registries
#

The Auction House is WoW’s economy. Players buy and sell items (crafting materials, gear, consumables) in an open market. Prices fluctuate based on supply and demand. Some players spend more time on the Auction House than in raids.

Package registries are the Auction House.

npm, PyPI, Maven Central, RubyGems: open markets where developers distribute code. Most of it is free, but the economics are the same. Supply and demand determine which packages thrive. Quality varies wildly.

WoW teaches caution with the Auction House. That cheap flask might be underpriced for a reason. That epic bind-on-equip item might be a scam.

npm teaches the same caution. That package with 10,000 weekly downloads might have a security vulnerability. That library with the slick README might be abandonware. The left-pad incident was an Auction House crash: a critical commodity disappeared and the market panicked.

The WoW player’s defense: know the market, check prices, don’t buy suspicious deals. The developer’s defense: audit dependencies, check maintenance history, don’t install packages with three stars and no recent commits.

Addons: Developer Tooling
#

WoW’s addon system lets players customize their UI and extend their gameplay. Damage meters, boss mod warnings, raid frames, loot council tools: the default UI works, but serious players run dozens of addons.

Developer tooling is the addon ecosystem.

Linter, formatter, pre-commit hooks, custom IDE snippets, shell aliases, tmux configurations: the default development environment works, but serious developers customize extensively.

In WoW, the player who refuses to install boss mods dies to mechanics they could have seen coming. In software, the developer who refuses to use a debugger steps through logs they could have inspected visually.

But WoW also teaches addon discipline.

Too many addons cause conflicts, crashes, and performance problems. Players who install every addon they find spend more time configuring their UI than playing the game. The best players use a focused set of addons that solve specific problems.

Developer tooling needs the same discipline. A developer who spends more time configuring tools than writing code has forgotten the purpose of the tools. The best toolchains are minimal, focused, and reliable.

Professions: Side Projects and Tooling
#

In WoW, characters can learn professions: blacksmithing, enchanting, engineering, alchemy. These secondary skills let players craft items, enhance gear, and create consumables.

Professions don’t advance the main quest. They don’t give experience. But they make the main quest easier.

Internal tooling is professions.

CLI tools, build scripts, code generators, monitoring dashboards: they don’t ship features, but they make shipping features faster. A team that invests in professions (that builds internal tools) levels faster than one that doesn’t.

The WoW lesson: max professions early.

A blacksmith who starts crafting at level 1 has far better gear than one who starts at max level. A team that builds tooling from day one has far better productivity than one that starts tooling after the crunch.

Threat and Aggro: On-Call and Incident Management
#

In WoW, every NPC enemy has a threat table. Whoever generates the most threat gets attacked. Tanks generate threat intentionally. Damage dealers generate threat as a side effect of dealing damage. Healers generate threat by healing.

If a damage dealer generates too much threat, the boss turns and kills them. This is called pulling aggro. It’s almost always fatal.

Production incidents have threat tables.

The on-call engineer is the tank. They absorb the pressure, pages, alerts, user complaints, Slack messages. They hold threat so the rest of the team can work without distraction.

But just like in WoW, if someone pulls aggro (if a non-on-call engineer starts making changes in production, or a manager starts demanding real-time updates every thirty seconds) the incident gets worse. The wrong person has the boss’s attention.

The WoW solution: let the tank hold threat. The incident solution: let the on-call engineer own the response. Everyone else supports (provides context, runs commands when asked, stays available) but doesn’t grab aggro.

A damage dealer who pulls aggro doesn’t just kill themselves. The boss might cleave and kill the healer too. A developer who pushes an untested fix during an incident doesn’t just fail to resolve the issue: they might make it worse and take down another system.

Let the tank tank.

Enrage Timers: Deadlines
#

Many raid bosses have an enrage timer. After a fixed duration, the boss enters an enraged state: damage increases dramatically, new mechanics activate, and the raid will wipe within seconds.

The message is simple: be good enough, fast enough.

Software deadlines are enrage timers.

The quarterly OKR deadline. The conference demo. The enterprise client’s contract renewal date. These are fixed points in time after which the consequences escalate sharply.

WoW teaches that enrage timers create two strategies: out-gear the fight or out-skill the fight.

Out-gearing means coming back with better stats and burning the boss down before the timer. In software, out-gearing means adding more engineers, more resources, more hours to hit the deadline.

Out-skilling means executing perfectly, minimizing wasted time, and maximizing output with the resources at hand. In software, out-skilling means good architecture, clean code, and efficient processes.

The WoW meta has swung between both strategies across expansions. In software, the meta swings between hiring blitzes and efficiency drives. The answer, as always, is both: enough gear to survive, enough skill to execute.

Grinding: Maintenance Work
#

In WoW, some activities are just grinding.

Reputation grinds. Daily quests. Material farming. Running the same dungeon for the thirty-seventh time because the trinket won’t drop. Nobody enjoys grinding. But grinding is how players progress.

Software maintenance is grinding.

Updating dependencies. Fixing flaky tests. Rotating credentials. Cleaning up log files. Refactoring code that works but is hard to read. Nobody launches a software career to update dependency versions. But the grind is how the factory keeps running.

WoW players who skip the grinding find themselves under-geared when new content drops. They can’t participate in the new raid because they didn’t do the preparatory work.

Teams that skip maintenance find themselves unable to ship when new features are needed. The dependency tree is two years out of date. The test suite takes forty minutes. The deployment process is manual and error-prone. They can’t ship because they didn’t do the preparatory work.

The grind isn’t glamorous. But it’s what separates the prepared from the unprepared.

Expansions: Major Rewrites
#

Every few years, WoW releases an expansion.

A new continent. New systems. New mechanics. Sometimes, old systems are completely rebuilt. Stats are squished. Abilities are pruned. The talent tree is redesigned. The game I knew is fundamentally changed.

Some changes are loved. Some are hated. Every expansion has players who threaten to quit and players who return after years away.

Major platform rewrites are expansions.

A migration from monolith to microservices. A transition from on-premise to cloud. A framework upgrade from v2 to v3. The system I knew is fundamentally changed.

Like WoW expansions, major rewrites are risky. They take enormous investment. They disrupt existing workflows. They might attract new users or they might alienate existing ones.

WoW’s approach to expansions is instructive: the core identity stays the same. Despite every expansion’s changes, WoW is still about questing, dungeons, raids, and gear. The systems change. The core doesn’t.

Successful rewrites do the same. The core business logic is preserved. The deployment infrastructure might change, the data store might change, the frontend framework might change, but the product’s purpose stays the same.

Don’t change what the game is about. Change how the game plays.

Heirloom Gear: Reusable Components
#

In WoW, heirloom items are special pieces of gear that scale with a character’s level.

I earn them on my max-level character and mail them to my alts, my alternate characters. A level 1 alt wearing heirloom gear is dramatically stronger than a level 1 character in normal gear. The investment I made on my main character benefits every alt.

Design systems and shared libraries are heirloom gear.

A component library built by one team makes every subsequent team faster. A shared authentication module, a common logging framework, a standardized deployment pipeline: these are investments that benefit the entire organization.

The WoW lesson: invest in heirlooms early.

Players who acquire full heirloom sets for their alts level twice as fast. Organizations that invest in shared infrastructure ship twice as fast. The upfront cost is significant (farming the currency to buy heirlooms, or building a design system instead of shipping features) but the compound return is enormous.

The Late Game: Software Factories
#

In WoW’s late game, the most efficient guilds stop running content manually.

They sell raid carries, experienced groups that carry less-skilled players through content for gold. They run GDKP splits, systematic distribution of loot based on a bidding system. They have addon rotations that automate cooldown tracking, buff management, and consumable usage.

The game transitions from playing to orchestrating.

Software factories are the late game of development.

I stop writing code manually. I write specifications that AI agents implement. I stop running tests manually. I design verification systems that run automatically. I stop deploying manually. I build pipelines that ship code continuously.

Like WoW’s late game, running a software factory requires an enormous investment in infrastructure.

A guild can’t sell raid carries without first clearing the raid dozens of times. A team can’t run a software factory without first building the CI/CD, the testing infrastructure, the monitoring, and the AI tooling.

Guilds that try to skip to carry runs without learning the mechanics get exposed when the buyer notices they’re failing. Teams that try to skip to software factories without the infrastructure get exposed when the AI-generated code doesn’t work, doesn’t test, and doesn’t deploy.

Clear the raid first. Then sell the carry.

The Lesson
#

World of Warcraft is a game about progression through coordination.

I start alone, killing boars in a starting zone. I end in a raid of twenty-five, executing a complex sequence of mechanics that requires every player to perform their role flawlessly. The satisfaction isn’t in the gear: it’s in the coordination.

Software development is the same game.

We start alone, fixing bugs in a codebase we don’t understand. We end in organizations of hundreds, shipping systems that require every team to perform their role flawlessly. The satisfaction isn’t in the code: it’s in the coordination.

In WoW, every expansion resets the gear but not the skill. The players who clear content first aren’t the ones with the best loot: they’re the ones who’ve been playing longest, who understand the mechanics deepest, who coordinate most tightly.

In software, every project is different but the fundamentals are the same. The teams that ship fastest aren’t the ones with the most tools: they’re the ones who’ve been building longest, who understand the trade-offs deepest, who coordinate most tightly.

If I’m still solo questing, it’s time to join a guild. If I’m still running dungeons, it’s time to raid. If I’m still equipping greens, it’s time to earn my epics.

For the Horde. Or the Alliance. Just pick a side.

See also
#


Code Factories: Or How I Learned to Stop Worrying and Build the Belt

I land on an alien planet with nothing but a pickaxe and a furnace.

That’s Factorio. It’s also my first day as a software developer.

In Factorio, I crash-land and must build a rocket to escape. I start by hand-mining iron ore, smelting it in a stone furnace, and crafting simple items. Within hours, I’ve built conveyor belts that carry ore automatically, assemblers that craft without me, and trains that shuttle materials across the map. The factory grows. I go from doing everything myself to watching machines do everything for me.

Software development is following the same trajectory. The question is whether I’m still hand-mining iron ore.

The Belt: The CI/CD Pipeline
#

In Factorio, the conveyor belt is the first automation I build. Instead of walking back and forth carrying ore, I lay down a belt and let it move resources while I do something else.

The CI/CD pipeline is the belt. Every time I push code, tests run, builds compile, deployments ship. I don’t walk the ore to the furnace anymore. The belt carries it.

Teams without CI/CD are the players who never unlock belts. They’re still carrying ore by hand, one commit at a time, manually deploying to servers, manually running tests. It works when the team is small. It doesn’t scale.

Assemblers: The Build System
#

After belts come assembling machines. I feed them ingredients and they output a product. I don’t craft gears by hand anymore (the assembler does it, faster and without mistakes).

Compilers, bundlers, transpilers: these are the assemblers. I feed them source code and they output runnable software. I used to manage dependencies by hand, include scripts individually, and pray the versions matched. Now the assembler handles it.

The parallel goes deeper. In Factorio, I quickly learn that one assembler isn’t enough. I need a chain: iron ore becomes iron plates, iron plates become gears, gears become transport belts. Each step is its own assembler, fed by belts from the previous one.

The build pipeline works the same way. Source code becomes transpiled code, transpiled code becomes bundled assets, bundled assets become container images, container images become deployed services. Each stage is an assembler in a chain. If one assembler is slow, the whole chain backs up. If one assembler breaks, nothing after it gets built.

Inserters: The Integration Points
#

Inserters are the quiet heroes of Factorio. They take items from belts and put them into assemblers, furnaces, and chests. They’re the glue between every machine.

Integration points in software are the inserters. APIs, webhooks, message queues, event streams: they move data between services. Nobody talks about them at conferences. But when an inserter stops working in Factorio, the assembler starves. When an integration point breaks in production, the service starves.

Most production outages aren’t caused by a broken assembler. They’re caused by a broken inserter, a misconfigured webhook, a timed-out API call, a corrupted message in a queue. The machines were fine. The connection between them failed.

The Main Bus: The Monorepo
#

As my Factorio factory grows, I face a critical design decision: how to organize my belts. Most experienced players converge on the same solution, the main bus.

A main bus is a wide highway of parallel belts carrying every resource I need, running in a straight line across my factory. I branch off production lines from the bus, pull what I need, and return byproducts. It’s not the most space-efficient design. It’s not the fastest. But it’s the most understandable, and in a game where my own factory can become incomprehensible, understandability is survival.

A monorepo is the main bus. All the code, all the services, all the shared libraries in one place, organized in a predictable structure. Teams branch off to build their services, pull shared dependencies from the bus, and contribute back. Like Factorio, the monorepo isn’t optimal in every dimension. But when a new developer joins and needs to understand how everything connects, they follow the bus. No archaeology required.

Teams that reject the main bus in Factorio end up with spaghetti, belts crisscrossing everywhere, impossible to trace, impossible to modify without breaking something. Teams that reject the monorepo end up the same way: dozens of microservices with undocumented dependencies, where nobody knows which service calls which, and changing one API breaks three things nobody knew existed.

Logistics Bots: The AI Agents
#

At some point in Factorio, I unlock logistic robots. Flying drones that carry items anywhere in my network. They don’t need belts. They don’t follow paths. I request an item, and a bot brings it.

AI coding agents are the logistics bots. I ask for a function, and the agent writes it. I ask for tests, and the agent generates them. I ask for a bug investigation, and the agent traces the stack. They don’t need me to lay down a belt first. They go directly to the source and bring back what I need.

But here’s what Factorio teaches about bots: they don’t replace belts. Players who try to run everything on bots discover that bots have a capacity limit. When the network gets busy, bots queue up, delivery times spike, and the factory starves. The best factories use bots for the weird, one-off requests and keep belts for the high-throughput, predictable flows.

The best engineering teams do the same. AI agents handle the ad-hoc tasks, the one-off scripts, the bug investigations, the documentation updates. But the core pipeline (the build system, the CI/CD, the deployment process) runs on belts. Predictable. Reliable. Fast.

The Ratios: The System Architecture
#

In Factorio, every recipe has precise ratios. To produce one science pack per second, I need exactly 1.25 assemblers making gears and 0.8 assemblers making copper cable. The math is deterministic. If I get the ratios wrong, I get bottlenecks. One belt backs up while another starves. Resources pile up where they’re not needed and run dry where they are.

System architecture has the same dynamics, just less precise. Every service has throughput limits. Every database has connection pool limits. Every queue has a maximum depth. If the authentication service can handle 100 requests per second but the API gateway is sending 200, there’s a bottleneck. The requests pile up. Timeouts cascade. Users see errors.

Factorio players solve ratio problems with calculators and spreadsheets. They plan their factory before they build it. Software engineers solve the same problems with load testing and capacity planning, or they should. Too many teams build first and measure later, then wonder why production is slow.

Biters: The Production Incidents
#

The alien natives in Factorio are called biters. They attack the factory in increasing waves, drawn by the pollution the machines produce. The more I build, the more they attack. I can ignore them for a while, but eventually they’ll overwhelm my defenses.

Production incidents are the biters. They come in waves, drawn by the complexity of the system. The more services I deploy, the more dependencies I add, the more incidents I attract. I can ignore them for a while, patch the symptom, restart the service, move on. But eventually they’ll overwhelm me.

In Factorio, the solution isn’t to stop building. It’s to build defenses: walls, turrets, artillery. In software, the solution isn’t to stop deploying. It’s to build defenses: monitoring, alerting, automatic rollback, chaos engineering.

The best Factorio players don’t just react to biter attacks. They proactively clear nests before they evolve. The best engineering teams don’t just react to incidents. They proactively eliminate failure modes before they cause outages.

Throughput vs Latency: The Eternal Trade-off
#

Factorio players eventually discover that throughput and latency are different things. A belt with 100 items per minute has high throughput but items take time to travel from one end to the other. A bot delivery is low throughput (one item at a time) but low latency (it goes straight there).

Microservices vs monoliths is the same trade-off. A monolith has high throughput; everything runs in the same process, no network calls. But change latency is high; I deploy the whole thing even if I changed one function. Microservices have low change latency; I deploy one service independently. But throughput suffers from network overhead, serialization, and distributed coordination.

Factorio doesn’t judge me for choosing bots over belts or belts over bots. It just shows me the consequences. Software architecture should work the same way. I choose my trade-offs, but I stay clear about what I’m trading.

The Rocket: Shipping
#

The goal of Factorio is to launch a rocket. Everything I build (every belt, every assembler, every defense) exists to launch that rocket. The goal is easy to forget. Players spend hundreds of hours optimizing a single belt intersection, perfecting a circuit network, or making their factory look pretty. Meanwhile, the rocket sits unbuilt.

Software teams do the same thing. They refactor code that works fine. They migrate to the latest framework. They rebuild systems that don’t need rebuilding. Meanwhile, the product sits unshipped. The users sit unserved. The business sits unimproved.

Factorio teaches a simple lesson: the factory exists to launch the rocket, not the other way around. The code exists to ship the product. Every optimization that doesn’t serve the product is a belt to nowhere.

The Map: The Unknown Unknowns
#

When I start Factorio, the map is covered in fog. I don’t know where the iron is, where the oil is, or where the biters are nesting. I explore by walking into the fog, revealing terrain piece by piece. Sometimes I find a massive ore patch right next to my base. Sometimes I walk into a biter nest and die.

Software development is exploring a fog of war. I don’t know what the users want until I ship. I don’t know what the legacy system does until I try to change it. I don’t know what the dependency actually does until it breaks in production.

The Factorio solution to the fog of war is radar. I build radar stations that slowly reveal the map around them. Not all at once, but gradually, giving me visibility without requiring me to walk everywhere.

Observability is the radar. Logging, metrics, tracing, dashboards: they don’t eliminate the unknown, but they reveal it gradually. I can’t see everything. But I can see enough to make good decisions.

Pollution: Technical Debt
#

Every machine in Factorio produces pollution. Pollution spreads across the map and triggers biter attacks. More machines, more pollution, more attacks. Pollution is the cost of growth.

Technical debt is pollution. Every shortcut, every hack, every “we’ll fix it later” generates debt. Debt spreads through the codebase, making changes harder, triggering bugs, slowing development. More code, more debt, more incidents.

I can’t eliminate pollution in Factorio without eliminating production. I can’t eliminate technical debt without eliminating software. The key is management: build efficiently, clean up regularly, and invest in infrastructure that reduces the debt per feature shipped. Electric furnaces produce less pollution than steel furnaces. Good abstractions produce less technical debt than bad ones.

The Late Game: Software Factories
#

In the late game of Factorio, something interesting happens. I stop building things myself entirely. Instead, I design blueprints, templates for entire sections of factory. I place a blueprint and construction bots build the whole thing automatically. I’m no longer an assembler. I’m an architect.

Software factories are the late game of software development. I don’t write code. I write specifications. I don’t review code. I design verification systems. I don’t debug. I design healing systems.

Like Factorio’s late game, the software factory requires an enormous upfront investment. I need to have built the belts, the assemblers, the bots, the logistics network before I can stamp down blueprints. Software factories require CI/CD, testing infrastructure, monitoring, and AI agents before they can operate autonomously.

Players who try to skip to blueprints in Factorio without building the infrastructure first find that their construction bots can’t reach the build site, don’t have materials, or build the wrong thing. Teams that try to skip to software factories without the infrastructure find that their AI agents produce broken code, can’t deploy, and create more problems than they solve.

The Spidertron: Autonomous Agents
#

The Spidertron is Factorio’s ultimate vehicle. A walking base that I can remote-control, equip with rockets, and send into dangerous territory. It’s the end result of everything I’ve built: it uses the tech I researched, the weapons I crafted, the logistics network I established.

Autonomous AI coding agents are the Spidertron of software development. They roam the codebase, make changes, run tests, deploy code, all while I watch from the map. But like the Spidertron, they’re only as good as the infrastructure behind them. A Spidertron without researched weapons is a walking target. An AI agent without a testing infrastructure is a liability.

The Lesson
#

Factorio is a game about building something that builds itself. I start by doing everything manually. I end by watching machines do everything for me. The satisfaction isn’t in the automation itself: it’s in designing a system that works, that’s elegant, that grows.

Software development is the same game. I start by writing code manually. I end by designing systems that write, test, and deploy code without me. The satisfaction isn’t in the code: it’s in the factory.

If I’m still hand-crafting every iron gear, it’s time to build my first assembler. If I’m still carrying ore by hand, it’s time to lay down a belt. If I’m still reviewing every line of code myself, it’s time to build a verification system.

The factory must grow.

See also
#


Code Factories: The StarCraft Perspective

You start with four workers, a command center, and fog of war in every direction.

That’s StarCraft. It’s also your first day at a startup.

In StarCraft, you command one of three races (Terran, Protoss, or Zerg), each with radically different economies, armies, and strategies. You gather minerals and vespene gas, build structures, research upgrades, and produce units. You scout the opponent, react to their strategy, and try to win through superior economy, tactics, or both. The clock never stops. The other player never waits.

Building a software organization is the same game with different units. The question is which race you’re playing and whether you know it.

APM: Developer Productivity
#

In StarCraft, APM (actions per minute) is the raw measure of how fast a player can issue commands. Pros sustain 300+ APM over games that last 20 to 40 minutes. Beginners hover around 30.

But high APM doesn’t win games. Efficient APM does. A pro spends most of those actions on macro (building workers, expanding, producing units) and only the necessary actions on micro, controlling individual units in combat. A beginner wastes APM clicking the same unit six times or panicking during a fight.

Lines of code per day is the APM of software development. It measures activity, not impact. A developer who writes 500 lines in a day isn’t necessarily more productive than one who writes 50. The 50-line developer might have deleted 200 lines, simplified an abstraction, or prevented a week of debugging.

The StarCraft lesson: optimize for effective actions, not total actions. In code, optimize for value shipped, not code written.

Worker Production: Hiring
#

In StarCraft, the single most important thing a new player can learn is to never stop making workers. Workers gather resources. Resources fund everything else: units, buildings, upgrades. A player who stops producing workers at the five-minute mark will be economically crushed by one who didn’t, regardless of army composition or tactical skill.

Hiring is your worker production. Every engineer you add increases your resource gathering rate, the rate at which your team can design, build, and ship software. A team that stops hiring after its founding engineers will be outpaced by a team that kept recruiting, even if the founding team was brilliant.

But StarCraft also teaches that worker production has a ceiling. You can only send so many workers to a mineral patch before they queue up and waste time. In software, the ceiling is communication overhead. Add too many engineers to a project and they spend more time coordinating than building. Brooks said it decades ago in The Mythical Man-Month: adding people to a late project makes it later. StarCraft players learn it every game: there’s an optimal number of workers per base, and exceeding it wastes resources.

Expanding: New Teams and Services
#

In StarCraft, one base isn’t enough. The mineral patches deplete. Gas geysers run dry. To keep growing, you must expand, build a new command center, nexus, or hatchery at a new resource location.

Each expansion is a bet. It costs resources to build. It takes time to become profitable. And the expansion is vulnerable: spread across the map, harder to defend, exposed to attack.

Starting a new team or service is expanding. You invest resources (hiring, onboarding, infrastructure) in exchange for future throughput. The first team’s codebase, like a mineral patch, eventually becomes congested. Too many engineers working on the same service creates merge conflicts, deployment bottlenecks, and architectural compromises. A new team with its own service spreads the load.

But like StarCraft expansions, new teams are vulnerable. They don’t yet know the codebase, the domain, or the culture. They’ll make mistakes the first team already learned from. They’ll build things that duplicate or conflict with existing systems. And they require protection (mentoring, clear interfaces, architectural guidance) or they’ll be overrun by the complexity the first team already tamed.

StarCraft players know: expand when your main base is saturated, not when you’re under attack. Software leaders should know: create new teams when the current team is at capacity, not when the project is already late.

The Supply Cap: Organizational Scaling
#

In StarCraft, you can’t just build an infinite army. Every unit costs supply. Terran supply depots, Protoss pylons, Zerg overlords: each race has its own mechanism for increasing the supply cap. If you hit the cap, production halts. Your factories, barracks, and starports sit idle until you build more supply.

Organizational scaling has supply caps too. They just aren’t as explicit.

The first cap is communication. A team of 5 people has 10 communication channels. A team of 15 has 105. At some point, people spend more time talking than building, and adding another engineer actually decreases output.

The second cap is architecture. A monolith can support a certain number of contributors before merge conflicts, test suite times, and deployment coordination become unbearable. You need to split the monolith (build a pylon, if you will) to increase the cap.

The third cap is process. A small team doesn’t need sprint planning, architecture review boards, or release managers. A large team does. Each process is a supply depot: it costs resources to build but increases the number of people who can work together productively.

Teams that ignore the supply cap wonder why their army is small despite having plenty of factories. The factories are there. The supply isn’t.

Build Orders: Project Plans
#

Every StarCraft game begins with a build order, a planned sequence of actions for the first few minutes. Build a supply depot at 10 supply. A barracks at 12. A refinery at 13. Expand at the natural at 20.

Build orders aren’t rigid scripts. They’re opening principles, a sequence that has been proven to lead to a strong mid-game position. Players deviate when they scout something unexpected, but they always have a plan to return to.

Project plans are build orders. You don’t start building features randomly. You have a sequence: set up the repository, configure CI/CD, build the core domain model, add the API layer, implement authentication, deploy to staging. The order matters because each step depends on the previous one.

But just like in StarCraft, the build order only covers the opening. After the first few minutes, the game becomes dynamic. You react to what you see. You adapt to the opponent’s strategy. The build order gave you a strong position: it didn’t win the game.

Agile methodology is the StarCraft mid-game. You’ve executed your build order; the project is set up, the architecture is sound. Now you play reactively, adjusting to user feedback, market changes, and technical surprises. The build order got you here. Reaction wins the game.

Scouting: User Research
#

In StarCraft, if you don’t scout, you die. Period. A player who builds the wrong units because they didn’t know the opponent was going air gets crushed. A player who expands into a choke point the opponent already controls loses the expansion. Information is more valuable than any unit.

User research is scouting. If you don’t talk to users, watch them use your product, read their support tickets, and analyze their behavior, you’re building blind. You might be building the perfect counter to a strategy the opponent isn’t using. You might be expanding into territory nobody wants.

StarCraft players send a worker to scout at supply 13. They sacrifice a unit to gain information. Good software teams do the same: they sacrifice development time to talk to users, run usability tests, and analyze metrics. The cost of scouting is always less than the cost of building the wrong thing.

Tech Trees: Technology Choices
#

Every StarCraft race has a technology tree. You can’t build battlecruisers without a starport, a fusion core, and an armory. You can’t research stimpack without a tech lab on your barracks. Each technology unlocks new capabilities but requires investment in the prerequisite technologies.

Technology stacks are tech trees. You can’t deploy containers without a container runtime. You can’t run Kubernetes without understanding networking, DNS, and certificate management. You can’t implement real-time features without WebSockets, which requires understanding persistent connections, which requires understanding your load balancer’s timeout settings.

The StarCraft lesson about tech trees is simple: don’t tech too fast and don’t tech too wide.

Teching too fast means skipping army production to rush advanced technology. In StarCraft, this loses to an early attack. In software, this means spending months building infrastructure while shipping nothing. The business can’t wait for your perfect Kubernetes setup. Ship something with simpler tech and upgrade later.

Teching too wide means researching every upgrade simultaneously. In StarCraft, this commits resources to too many upgrades at once and leaves you weak everywhere. In software, this means adopting every new framework, database, and tooling option. Your team can’t be experts in everything. Pick a path through the tech tree and commit to it.

Unit Composition: Team Composition
#

In StarCraft, army composition matters more than army size. A player with 50 marines loses to a player with 10 banelings and 20 zerglings. A player with 20 stalkers loses to a player with 10 immortals. Each unit has strengths and weaknesses, and the right combination is stronger than any individual unit.

Team composition works the same way. Ten frontend developers can’t build a backend service. Ten senior engineers can’t ship quickly without junior engineers handling the simpler tasks. Ten generalists can’t match a team with specialized expertise in security, performance, and DevOps.

The ideal StarCraft army mixes unit types that cover each other’s weaknesses. Marines deal high damage but are fragile; medivacs keep them alive. Zealots are strong in close combat but slow; sentries create force fields to trap enemies.

The ideal software team mixes skills the same way. Backend engineers build the services. Frontend engineers build the interfaces. DevOps engineers build the infrastructure. Security engineers build the defenses. No single role can win the game alone.

Multitasking: Context Switching
#

StarCraft demands multitasking. While your army fights at the front, your economy must keep producing at home. While you scout the enemy, your upgrades must keep researching. Neglect one task and the whole performance suffers.

Software development demands the same. While you write code, production issues arise. While you debug a problem, meetings are scheduled. While you plan the next sprint, the current sprint falls behind.

StarCraft players learn to use control groups, binding units and buildings to hotkeys so they can jump between tasks instantly. Press 1, manage the army. Press 2, build workers. Press 3, research upgrades. The hotkeys don’t reduce the number of tasks, but they reduce the cost of switching between them.

In software, your control groups are your tools and workflows. A good IDE setup lets you switch between files instantly. A good terminal setup lets you switch between environments instantly. A good project management tool lets you switch between tasks instantly.

But StarCraft also teaches that there’s a hard limit to multitasking. Even pros can’t manage five simultaneous drops, a base race, and an upgrade timing all at once. They prioritize. They let minor fights play out automatically while they manage the critical ones.

Software developers need to learn the same lesson. You can’t context-switch between five tasks and do any of them well. Prioritize the critical path. Let minor tasks wait. Not everything is a drop in your mineral line.

Creep Spread: Codebase Quality
#

The Zerg provide the clearest metaphor for codebase quality. Creep is the organic substance that Zerg structures generate, spreading across the ground. Zerg units move faster on creep. Zerg structures can only be built on creep. Creep tumors extend the network, and a well-spread creep carpet gives the Zerg player vision, mobility, and territorial control.

Codebase quality is creep spread. Good test coverage, clear documentation, consistent naming conventions, and well-defined interfaces: these are your creep tumors. Each one extends the area where future development moves faster. New engineers onboard more quickly on a well-documented codebase. Refactoring is safer with comprehensive tests. Features ship faster when the interfaces are clean.

Terran and Protoss players hate creep. It gives the Zerg vision and speed in territory that should be neutral. Technical debt is the reverse: it gives bugs and confusion territory that should be clean. Every hardcoded value, every undocumented assumption, every god class is an area where development slows down and more bugs appear.

The Zerg lesson: invest in creep spread early and often. A Zerg player who tumors aggressively in the first five minutes controls the map in the tenth. A team that invests in code quality early ships faster in the long run. Not because quality is its own reward, but because quality compounds.

Ladder Anxiety: Imposter Syndrome
#

Every StarCraft player knows ladder anxiety. That feeling before clicking the “Find Match” button, the fear of losing, of being exposed as a fraud, of dropping a league and having everyone see.

The anxiety is universal. Grandmasters feel it. Day9 famously talked about how terrified he was to play his placement matches, and he was one of the best players in the world.

Imposter syndrome in software is ladder anxiety. The fear of submitting a pull request because your code might be wrong. The fear of speaking up in an architecture meeting because your idea might be bad. The fear of applying for a senior role because you might not be good enough.

StarCraft players overcome ladder anxiety the same way every time: by playing. Not by studying build orders. Not by watching replays. By clicking the button and playing the game. Losses stop hurting after the hundredth one. Wins start feeling earned.

Software developers overcome imposter syndrome the same way. Submit the pull request. Speak up in the meeting. Apply for the role. The fear doesn’t go away. You just learn that it’s not predictive of outcome.

Cheese: Shortcuts and Hacks
#

Every StarCraft player has been cheesed. A cannon rush in your mineral line. A proxy barracks outside your base. A six-pool of zerglings that arrives before you have any defense.

Cheese strategies are high-risk, high-reward. They win quickly against unprepared opponents and lose decisively against prepared ones. Nobody wins a tournament with cheese alone. But everyone encounters it, and everyone has to learn to defend against it.

Technical shortcuts are cheese. Copy-pasting code from Stack Overflow without understanding it. Deploying directly to production without tests. Hardcoding a configuration value because you’re in a hurry.

Like StarCraft cheese, technical shortcuts work in the short term. The code runs. The feature ships. The deadline is met. But the opponent (in this case, future you or your teammate) is unprepared for the consequences. The hardcoded value becomes a production incident. The untested code breaks in an edge case. The copy-pasted solution has a security vulnerability.

StarCraft players learn to scout for cheese early and defend against it. Software developers need to do the same. Code review catches shortcuts before they merge. Linting and static analysis catch them before they deploy. The defense doesn’t have to be elaborate, just present.

The Late Game: Software Factories
#

In the late game of StarCraft, something shifts. Individual battles matter less than economy and production. The player with more bases, more production facilities, and better upgrades wins through attrition. They replace losses faster. They tech-switch faster. They recover from setbacks faster.

Software factories are the late game of software development. Individual code contributions matter less than the systems that produce them. The team with better CI/CD, better testing infrastructure, better monitoring, and better AI tooling ships faster. They recover from incidents faster. They adapt to changing requirements faster. They replace departing engineers faster.

In StarCraft, the late game rewards the player who invested in economy during the early and mid game. The player who cut workers to build a bigger army might win a battle, but they lose the war. In software, the late game rewards the team that invested in infrastructure when it would have been faster to just ship features. The team that skipped tests to hit a deadline might ship faster this quarter, but they slow down every quarter after.

Playing the Race: Choosing Your Stack
#

In StarCraft, race selection defines everything. Terran is positional and mechanical (siege tanks, bunkers, planetary fortresses). Protoss is elegant and powerful (expensive units, warp-in mechanics, force fields). Zerg is swarm-like and reactive (expendable units, rapid reinforcement, creep spread).

Each race rewards a different mindset. A player who tries to play Terran like Zerg (aggressive, expendable, swarm-like) loses. A player who tries to play Protoss like Terran (defensive, positional, slow) loses. You have to play your race’s strengths.

Technology stacks are races. A Python/Django stack rewards rapid development and convention-over-configuration (Protoss-like elegance). A Java/Spring stack rewards enterprise robustness and type safety (Terran-like positional strength). A Go microservices stack rewards simplicity, concurrency, and operational efficiency (Zerg-like speed and resilience).

Teams that try to fight their stack’s nature lose. Using Python for high-performance computing. Using Java for rapid prototyping. Using Go for enterprise business logic. Each can work, but each is fighting the race’s design.

Play your race. Or in StarCraft terms: pick Random, learn all three, and choose the one that fits the game you’re playing.

The GG: Knowing When to Refactor
#

In StarCraft, there’s a moment every player must learn to recognize: the game is lost. Your economy is destroyed. Your army is gone. Your opponent has three bases to your one. Fighting on is admirable but wasteful.

Good players type “gg” (good game) and leave. Not because they’re quitters. Because the time spent losing a doomed game is better spent starting a new one where they can apply what they learned.

The software equivalent is knowing when to rewrite. Not every codebase can be saved. Sometimes the technical debt is so deep, the architecture so convoluted, the assumptions so wrong, that incremental improvement is slower than starting fresh.

But here’s where the StarCraft analogy gets tricky. In StarCraft, a new game starts clean. In software, a rewrite inherits the constraints of the existing system: the users, the data, the integrations. The “gg” in software isn’t abandoning the project. It’s recognizing that the current implementation has reached the point of diminishing returns and a new approach will serve everyone better.

StarCraft players learn to recognize the threshold through experience. They don’t quit at the first setback. They quit when recovery becomes impossible. Software teams need the same judgment. Don’t rewrite at the first sign of technical debt. Rewrite when the debt makes every change slower than a fresh start would be.

The Lesson
#

StarCraft is a game of simultaneous decisions under time pressure. You manage economy, technology, army composition, map control, and reconnaissance all at once, while an opponent does the same and tries to disrupt you. The best players aren’t the ones with the fastest hands: they’re the ones who make better decisions about where to invest their attention.

Software development is the same game. You manage features, infrastructure, team composition, code quality, and user feedback all at once, while the market changes and competitors advance. The best teams aren’t the ones who write the most code: they’re the ones who make better decisions about where to invest their resources.

In StarCraft, every game is different. The map changes, the opponent changes, the meta shifts. But the fundamentals remain: workers gather resources, buildings unlock technology, scouting reveals information, and good decisions win games.

In software, every project is different. The domain changes, the team changes, the technology shifts. But the fundamentals remain: engineers build features, infrastructure enables scale, user research reveals needs, and good decisions ship products.

If you’re still playing single-player, it’s time to scout the map. If you’re still on one base, it’s time to expand. If you’re still manually producing every unit, it’s time to set a rally point.

GL HF.

See also
#


task-stack - A persistent task stack that lives in your system tray

I’ve been using the workstack concept for years to track what I’m working on and where I got interrupted. task-stack is the natural evolution: a small system tray app that keeps a persistent, reorderable stack of tasks always one hotkey away.

The top of the stack is your current task. Everything below the top entry is queued. Press Ctrl+Shift+T from anywhere and a compact window appears where you can add, reorder, promote, and remove tasks. Close the window and the app stops taking screen space. The tray icon always shows the current task as its tooltip.

Why a stack, not a list
#

Todo lists are flat. Kanban boards carry more overhead. When you’re deep in flow and get interrupted, you don’t want to prioritize a backlog: you want to push something on top of what you’re doing and pop it off when you’re done.

A stack models interruptions naturally:

  • Push: a new urgent task goes on top and becomes the current task.
  • Pop: mark the task done and the next task becomes current automatically.
  • Reorder: something can wait? move the task down. Something urgent? promote the task to the top.

No projects, no tags, no due dates. Just a stack of things to do, in order.

Features
#

  • System tray icon with the current task as tooltip and a “Mark Done (pop)” action.
  • Global hotkey (default: Ctrl+Shift+T, configurable) to bring the stack window forward from any application.
  • Keyboard-driven editing: add tasks with Enter, reorder with arrow keys, promote with /, remove with Backspace. Full shortcut table in the README.
  • Persistent state in ~/.task-stack.yaml. Easy to inspect, back up, or version control.
  • Soft deletes: removed tasks stay in the YAML file with a deleted_at timestamp, so you keep a full history.
  • Timestamps: each task tracks created_at, started_at (first time the task became current), and last_current.
  • Cross-platform: works on macOS, Linux, and Windows.

Quick start
#

git clone https://github.com/TomzxCode/task-stack.git
cd task-stack/python
uv sync
uv run task-stack

The app starts in the system tray. Press the hotkey or pick “Open Stack” from the tray menu.

Data format
#

Tasks are stored in ~/.task-stack.yaml as a simple YAML list:

- text: Write blog post about task-stack
  created_at: '2026-05-02T10:00:00+00:00'
  started_at: '2026-05-02T10:00:00+00:00'
  last_current: '2026-05-02T10:30:00+00:00'
- text: Review pull requests
  created_at: '2026-05-02T09:00:00+00:00'
  deleted_at: '2026-05-02T09:45:00+00:00'

Active tasks come first in stack order. Soft-deleted tasks are appended at the end with a deleted_at timestamp. Settings (window geometry, hotkey) live in ~/.task-stack.settings.yaml.

Configure the hotkey
#

Edit ~/.task-stack.settings.yaml:

hotkey: ctrl+shift+t
# hotkey: alt+space
# hotkey: cmd+shift+space

Restart the app to apply the new hotkey. The current hotkey is shown in the tray menu.

When task-stack is useful
#

  • Developers context-switching between code reviews, bug fixes, and feature work. Push the interruption on the stack, pop the interruption when done, resume what you were doing.
  • Anyone who works with interruptions and wants a lightweight way to track pending work without opening a full project management tool.
  • Time tracking enthusiasts who want started_at / last_current timestamps to reconstruct what they worked on during the day.

See also
#

  • Workstack - the original note-taking concept that inspired task-stack.

gh-cached - Browse GitHub issues and PRs without burning through your API rate limit

Note (2026-07-02): gh-cached has been merged into ghx.

I use the GitHub CLI (gh) heavily, and I kept hitting the API rate limit. The pain is worst when I’m triaging issues across multiple repos or reviewing a backlog of PRs. Every gh issue list, every gh pr view, every comment fetch costs API calls I don’t need to spend.

I built gh-cached to solve the rate limit problem. gh-cached is a standalone Go binary that wraps the GitHub GraphQL API and caches every response to disk, so subsequent commands read from the local cache instead of hitting GitHub again.

The problem
#

The official gh CLI is excellent, but it’s designed for live, one-off interactions. There’s no built-in caching layer. Running gh issue list twice in five minutes makes two API calls. Browsing hundreds of issues with their comments in a large repository burns through the rate limit fast.

The problem gets worse when AI coding assistants query GitHub on my behalf. Multiple agents, multiple tools, all hitting the same API. The rate limit becomes a bottleneck.

How gh-cached works
#

go install github.com/tomzxcode/gh-cached@latest

The cache lives at ~/.cache/gh-cached/<host>/<owner>/<repo>. Each issue and PR is stored as its own JSON file, including all comments.

Pre-populate the cache:

gh-cached cache                          # current repo
gh-cached cache --repo cli/cli           # any repo
gh-cached cache --cache-duration 120     # fresh for 2 hours

Browse issues and PRs from cache:

gh-cached issue list                     # open issues
gh-cached issue list --state all         # everything
gh-cached issue list --label bug         # filter by label
gh-cached issue list --author alice      # filter by author
gh-cached issue view 42 --comments       # view with comments

gh-cached pr list --state merged         # merged PRs
gh-cached pr list --draft                # draft PRs only
gh-cached pr view 10 --comments          # view with comments

When the cache is fresh, all filtering happens in-memory with zero API calls. When the cache is stale, gh-cached falls back to the GitHub API and updates the cache.

Why a separate tool instead of a gh extension?
#

Two reasons.

First, gh-cached uses GraphQL under the hood, which lets the tool fetch issues and PRs with their comments in fewer round trips than the REST API the official CLI defaults to. The cache-then-filter pattern also means one pre-fetch can be queried many ways without going back to GitHub.

Second, independence. gh-cached works with just a GH_TOKEN environment variable, or falls back to gh auth token if the GitHub CLI is already installed. No plugin registration, no extension marketplace, just a binary you put in your PATH.

The caching strategy
#

The tool uses different strategies depending on the command:

  • cache fetches everything (all states, with comments) and writes one JSON file per item. Skips items already cached within the --cache-duration window (default: 60 minutes).
  • issue list / pr list reads cached files and filter in-memory when fresh. Falls back to the API with server-side filters when stale.
  • issue view / pr view serves from the individual cached file if less than 60 minutes old. Otherwise fetches from the API and updates the cache.

A single gh-cached cache run gives fast, offline-capable access to all issues and PRs for the next hour.

Authentication
#

Set the token in the environment:

export GH_TOKEN=ghp_...
or
export GITHUB_TOKEN=ghp_...

Or just have gh installed and authenticated: gh-cached will use gh auth token as a fallback.

When gh-cached is useful
#

  • AI coding assistants that query GitHub repeatedly. Pre-populate the cache once and let tools read from disk instead of making redundant API calls.
  • Repository triage where hundreds of issues need scanning with different filters. One cache fetch, then instant in-memory filtering.
  • Working with multiple repositories where context switches are frequent. Cache each repo once and browse offline.
  • Rate-limited environments like CI pipelines or shared machines where every API call is limited.

What to Do Next
#

go install github.com/tomzxcode/gh-cached@latest
# or download a binary from https://github.com/TomzxCode/gh-cached/releases/tag/latest
gh-cached cache --repo your-org/your-repo
gh-cached issue list --state all
gh-cached pr list --state all

Profit-as-a-Service

Software-as-a-Service gave us recurring revenue. Platform-as-a-Service gave us managed infrastructure. The next abstraction is obvious in hindsight: Profit-as-a-Service.

The Pattern
#

Every major shift in the software industry has been about abstracting away complexity.

On-premise servers became cloud infrastructure. Custom software became SaaS subscriptions. Manual operations became automation.

Each layer removes something the customer previously had to manage themselves. Each layer turns a cost center into a service. Each layer makes the underlying complexity someone else’s problem.

Profit-as-a-Service is the logical conclusion of this trend. Instead of selling software that helps you make money, you sell the money-making itself.

What It Looks Like
#

A traditional SaaS company sells you a tool. You still need to figure out how to use it to generate revenue.

A Profit-as-a-Service company sells you an outcome. The tool is invisible. The process is invisible. You pay for the result.

Examples already exist:

  • Algorithmic trading platforms that let you deploy capital and collect returns without understanding the underlying strategies.
  • AI-powered dropshipping services that handle product selection, listing, pricing, and fulfillment while you provide the capital.
  • Automated content farms that generate SEO-optimized articles, monetize them with ads, and split the revenue with you.
  • AI sales agents that prospect, qualify, and close deals on your behalf, charging only a commission on closed revenue.
  • Robo-advisors that manage investment portfolios algorithmically, charging a fraction of traditional advisory fees.

In each case, the customer provides capital or data. The service provides everything else. Revenue is shared, not subscribed to.

Why Now
#

Three forces are converging to make Profit-as-a-Service viable at scale.

1. AI can now execute complex business processes autonomously
#

Large language models can write marketing copy, analyze markets, negotiate with customers, and generate code. Multi-agent systems can coordinate these capabilities into end-to-end business workflows. What previously required a team of specialists can now be done by a single API call chain.

2. Infrastructure is fully commoditized
#

Starting a business used to require incorporating, hiring, building software, and navigating regulations. Now you can spin up a fully operational e-commerce store in an afternoon using off-the-shelf tools. The barrier to entry for almost every digital business has collapsed to near zero.

3. Distribution is algorithmic
#

Social media algorithms, search engines, and ad platforms have made customer acquisition a math problem. If you can compute the expected value of an impression, you can acquire customers profitably at scale. AI is better at computing expected value than humans.

The Economics
#

The unit economics of Profit-as-a-Service are deceptively simple.

The service provider operates a system that generates revenue. The customer provides the input: capital, data, or access to a market. Revenue is split between the provider and the customer.

For the customer, the arrangement is attractive because:

  • No upfront investment in tools or expertise.
  • Risk is aligned (the provider only makes money if you make money).
  • Scalability is built in (the system can run 24/7 without human intervention).

For the provider, the arrangement is attractive because:

  • Revenue scales with customer success (no ceiling from fixed subscriptions).
  • Customer acquisition is easier (pay-for-performance is an easy sell).
  • Margins improve with scale (the same system serves many customers).

The critical metric is the spread between what the system generates and what it costs to operate. If a system generates $10,000/month per customer and costs $2,000/month to run, the provider can keep $4,000 and give the customer $4,000. Both parties are happy. The system scales linearly in cost but exponentially in value.

The Risks
#

Profit-as-a-Service is not without significant risks.

Alignment risk
#

When you outsource profit generation, you also outsource decision-making. The provider’s optimization target may diverge from yours, a textbook principal-agent problem. A trading algorithm might maximize short-term returns at the cost of long-term stability. A content farm might optimize for clicks at the cost of your brand reputation.

Concentration risk
#

If the service provider goes down, your revenue goes to zero. There is no fallback when the entire business process is a black box. Diversification across multiple providers becomes essential but difficult.

Regulatory risk
#

Financial services are heavily regulated. When you abstract away the details of money-making, you may also abstract away compliance. The line between “software service” and “financial service” is thin and getting thinner.

Race to the bottom
#

When the barrier to entry is low, competition drives margins toward zero. The first provider to offer automated dropshipping captures most of the value. The hundredth provider competes on price until nobody makes money.

Dependency trap
#

Once a business relies on Profit-as-a-Service, transitioning away is extremely difficult. The provider owns the process, the data, and the relationships. Switching costs are not just technical but operational and strategic.

The Spectrum
#

Profit-as-a-Service is not binary. It exists on a spectrum of how much of the profit-generating process is abstracted away.

Level 0: You do everything. You buy tools and operate them yourself. Traditional software.

Level 1: AI assists you. You use AI tools to accelerate specific tasks. Copilots and assistants.

Level 2: AI operates under your supervision. You define strategy, AI executes tactics. Current state of most AI-powered businesses.

Level 3: AI runs the process, you provide direction. You set constraints, AI handles the rest. Emerging today.

Level 4: AI runs everything, you provide capital. You fund the operation, AI decides how to deploy it. Algorithmic trading, robo-advisors.

Level 5: AI runs everything, including capital allocation. Fully autonomous business entities. None exist yet, but the trajectory is clear.

Most businesses today operate at Level 0 or 1. The opportunity is in moving up the spectrum.

Who Wins
#

The winners in the Profit-as-a-Service economy will be:

Platform providers who own the infrastructure that makes Profit-as-a-Service possible. If you operate the AI system that generates profit for thousands of businesses, you capture a slice of every dollar earned.

Capital providers who can efficiently allocate resources across multiple Profit-as-a-Service offerings. When starting a business requires no expertise, access to capital becomes the primary competitive advantage.

Specialists who can handle the edge cases that AI cannot. Regulatory compliance, strategic partnerships, and brand building remain human-dominated activities.

Arbitrageurs who identify Profit-as-a-Service opportunities before they become commoditized. The window between “novel” and “saturated” is shrinking, but the rewards for being early are enormous.

Who Loses
#

The losers will be:

Middlemen whose value proposition was information asymmetry. When AI can access and process all available information, intermediaries add no value.

Consultants who sold expertise that can now be codified. If your consulting practice can be reduced to a prompt, it will be.

SaaS companies that failed to move up the value chain. A CRM that helps you track sales will lose to an AI that makes sales for you.

Employees whose jobs consisted of executing repeatable business processes. This is the uncomfortable truth that applies across industries.

The Question
#

Profit-as-a-Service is not a prediction. It is a description of what is already happening.

The question for any business is not whether this trend will affect you. The question is whether you will be the provider or the customer.

If your business processes can be automated by AI, they will be. If you are the one automating them, you are the Profit-as-a-Service provider. If you are the one whose processes are being automated, you are about to become a customer.

Choose wisely.


The Future of Code Review: How AI Makes Human Review Obsolete

The traditional code review is ending. Not because it is unnecessary, but because it is becoming unnecessary.

For decades, code review has been a central practice of software engineering. Pull requests, peer reviews, endless rounds of comments: these practices are how we have maintained code quality. But AI is fundamentally changing that practice. In my view, the question is not whether AI will replace human code review, but how quickly.

The Problem With Human Code Review
#

Human code review suffers from three fatal flaws:

  1. It does not scale. As teams grow, review backlogs grow. Developers wait days or weeks for feedback, blocking progress.

  2. It is inconsistent. Reviews vary widely based on who is reviewing, when they are reviewing, and how tired they are.

  3. It is expensive. Senior engineers spend significant time reviewing code instead of building features. In high-cost engineering organizations, this adds up to millions of dollars annually.

The alternative, no reviews at all, is not viable either. Shipping unreviewed code leads to security vulnerabilities, bugs, and technical debt.

The AI Solution: Software Factories
#

A new paradigm is emerging: the Software Factory. Instead of humans reviewing code, AI systems verify, test, and heal code autonomously. The Software Factory is not theoretical, it is already running in production.

Consider StrongDM’s Software Factory, which launched in July 2025. A team of three people (a CTO, a senior manager, and a new hire) built a system that autonomously clones core products like Okta, Jira, and Slack. Their target: $1,000 per day per engineer in tokens. That sounds expensive until you realize what they are shipping.

How It Works
#

The Software Factory approach replaces human review with six verification layers:

1. Competitive Generation
#

Instead of one AI writing code, run three in parallel. Three models run in parallel, each generating a different implementation. An automated evaluator selects the best output based on passing tests, minimal diffs, and fewer dependencies. The cost of running three models is trivial compared to the quality gain.

2. Iterative Refinement (Trycycle)
#

Define the problem, write a plan, ask “is it perfect?” If not, try again. Implement, then ask “is it perfect?” If not, try again. Trycycle runs this loop autonomously for hours.

3. Scenario-Based Validation
#

Treat scenarios like machine learning holdout sets. Store acceptance scenarios outside the codebase, then have an LLM judge whether the implementation satisfies them. Instead of a binary “tests pass”, you get a probabilistic satisfaction score measuring trajectory toward success.

4. Observability and Healing
#

Every interaction in the system gets logged to an execution database (CXDB). A Healer agent monitors this database, clusters similar problems, and writes prescriptions. No human bug reports. No human triage. Just autonomous detection and fixing.

5. Digital Twin Testing
#

Clone critical external dependencies: Google Sheets, Slack, Jira, authentication providers. Build replicas that AI agents cannot distinguish from production. Test in the most realistic environment possible without touching actual production systems.

6. Adversarial Verification
#

Separate the coding agent from the verification agent. Have a third agent actively try to break what was built. Enforce that verification criteria are authored before code, not after. This separation prevents the common anti-pattern of writing tests to match implementation rather than specify behavior.

The Economic Case
#

This approach is not just about quality, it is about economics.

StrongDM’s team reports seeing 21% more tasks completed and 98% more pull requests shipped. One case study: Nubank migrated an eight-year ETL monolith (six million lines, one thousand engineers) from an 18-month timeline to weeks. That is an 8-12x efficiency improvement with 20x cost savings.

The breakeven point is 50-70 pull requests per month. Above that threshold, the AI factory costs less than human review while delivering higher velocity.

The Five-Level Evolution
#

Dan Shapiro at StrongDM describes five levels of AI-assisted development:

Level 0: Manual (you write everything) Level 1: Offloading discrete tasks (ChatGPT for regex) Level 2: AI-native tools (90% of “AI” developers today) Level 3: Human-in-the-loop manager (reviewing all code) Level 4: You are now a product manager (spec, argue, craft skills, check tomorrow) Level 5: Dark Factory (black box: specs → software)

Most teams today are stuck at Level 2 or 3. The future is Levels 4 and 5, where humans specify constraints and AI handles everything else.

What This Means for Engineers
#

Your job is not to write code. Your job is not to read code. Your job is to solve quality problems so the factory can run.

This approach requires a philosophical shift. Instead of “how do I review this code?”, ask “why am I doing this?” If you can describe what is wrong, you can automate it. If you can describe what quality looks like, you can codify it as a verification rule.

The era of human-centric development is ending. AI compilers will transform specifications into deployed software. Teams will consist of AI business analysts, AI DevOps engineers, AI QA specialists, and AI compilers.

What to Do Next
#

The transition does not happen overnight. A realistic 16-week roadmap:

Weeks 1-2: Install Trycycle skill and competitive generation pattern Weeks 3-4: Build execution database and scenario framework Weeks 5-6: Implement Healer agent for autonomous fixes Weeks 7-8: Build digital twins for critical integrations Weeks 9-12: Migrate existing codebase to spec-driven workflow Weeks 13-16: Fine-tuning and compounding learning

The results compound. Weeks 1-4 might yield 5-10x velocity on simple tasks. By week 16, teams report 2x monthly speed improvements with compounding gains continuing.

Open Questions
#

The transition is not a solved problem. Key research questions remain:

  • Is $1,000/day per engineer in tokens realistic or an outlier?
  • How do patterns learned in one domain transfer to another?
  • When does fine-tuning cost outweigh compounding benefits?
  • What specific patterns trigger unavoidable human review?
  • How do you validate security without human review of auth logic?

These questions are not blockers, they are opportunities for teams to pioneer solutions.

The End of an Era
#

The traditional code review served us well. But like manual testing before automated test suites, its time is passing. The future is not humans reviewing AI code. It is humans designing verification systems that make human review unnecessary.

The question is no longer whether your team will adopt this approach. The question is whether your competitors will adopt it first.

References
#

Primary Sources

StrongDM Software Factory. Production deployment of autonomous code generation systems. https://factory.strongdm.ai/

Kilroy. Open-source CLI for running StrongDM-style pipelines locally. https://github.com/danshapiro/kilroy

Attractor. Provider-agnostic framework for autonomous code generation. https://github.com/strongdm/attractor

Trycycle. Simple skill for iterative refinement loops. https://github.com/danshapiro/trycycle

Devin. AI-powered software engineering platform with fine-tuning capabilities. https://devin.ai/

Analysis and Commentary

Willison, Simon. “Software Factory.” https://simonwillison.net/2026/Feb/7/software-factory/

Shapiro, Dan. “The Five Levels.” https://www.danshapiro.com/blog/2026/01/the-five-levels/

Shapiro, Dan. “Dark Factories.” https://www.danshapiro.com/blog/2026/03/dark-factories/

Shapiro, Dan. “You Don’t Write the Code.” https://www.danshapiro.com/blog/2026/02/you-dont-write-the-code/

LukePM. “The Software Factory.” https://lukepm.com/blog/the-software-factory/

Latent Space. “Reviews Dead.” https://www.latent.space/p/reviews-dead

Case Studies

Nubank ETL Migration. Eight-year monolith migrated in weeks using Devin. https://devin.ai/

StrongDM Security Software. Autonomous cloning of Okta, Jira, and Slack. https://factory.strongdm.ai/


The Survival of the Smartest: Exploring Darwinian Software Development

Prompt
#

Write an article about Darwinian software development, the use of LLM swarms to identify the best solution to a problem.

Answer
#

In traditional software development, software is “built.” An architect designs a blueprint, and developers write the code. But with Generative AI, we are moving toward a paradigm where software is evolved.

Darwinian Software Development is an emerging methodology that uses “swarms” of Large Language Models (LLMs) to iterate, compete, and select the most efficient code through a process mirroring natural selection.

How the Swarm Works
#

Instead of asking a single AI to write a function, Darwinian development deploys a multi-agent system (a swarm) to tackle the same problem from different angles. The process generally follows four biological phases:

  • Variation (The Mutation): Multiple LLM agents are given the same prompt but with different system instructions. One might prioritize memory efficiency, another readability, and a third raw speed.
  • Competition (The Struggle for Life): The agents generate dozens of potential solutions. The solutions aren’t just checked for syntax; they are run in a “sandbox” against unit tests and edge cases.
  • Selection (Fitness Function): An automated “Judge” agent (or a specialized testing suite) evaluates the outputs. Only the code that passes the most tests with the lowest latency or resource consumption “survives.”
  • Heredity (Refinement): The winning code is then used as the “DNA” for the next generation. The swarm takes the best-performing snippet and attempts to optimize it further until a “perfect” solution is reached.

Why Swarms Outperform Single Models
#

The “Darwinian” approach solves the two biggest problems in AI-assisted coding: hallucinations and getting stuck on a single approach.

  • Error Correction: If one agent introduces a bug, the likelihood that five other agents will make the exact same error is low. The swarm acts as a self-healing mechanism.
  • Diverse Architectures: One LLM might get stuck on a specific logic path. A swarm explores many possible solutions across the fitness landscape, finding creative solutions a human (or a single AI) might never consider.
  • Performance Benchmarking: By racing agents against each other, the system naturally optimizes for performance.
Feature Traditional Development Single LLM Coding Darwinian Swarm
Speed Slow (Human-paced) Very Fast Fast (Iterative)
Reliability High (Human-vetted) Medium (Hallucination risk) Very High (Cross-vetted)
Optimization Manual Basic Automated/Evolutionary

The “Fitness Function” Problem
#

The biggest challenge in Darwinian development isn’t the AI; it’s the criteria. For natural selection to work, the environment must be rigorous. If your “fitness function” (the tests you use to judge the code) is poorly written, the AI can evolve to pass the tests while the code remains broken. This failure mode is known as reward hacking. To counter reward hacking, modern swarms often include “Adversarial Agents” whose only job is to write difficult unit tests that expose the flaws in the code generated by the other agents.

The Future: Software That Self-Improves
#

We are approaching a point where software won’t be static. Imagine a server that monitors its own performance and, upon detecting a bottleneck, spawns a Darwinian swarm to rewrite its own inefficient modules immediately. In this new world, the developer’s role shifts from writer to naturalist. You aren’t typing the lines; you are defining the environment in which the best code can emerge.


What Changes When Coding Agents Are Infinitely Parallel

Imagine you can run hundreds or thousands of coding agents in parallel. How would you use them? The interesting answer is not “do everything faster”, but rather what fundamentally changes when parallelism is cheap.

From Sequential Exploration to Parallel Search #

When you have one agent, you think carefully before acting, because going down dead ends is expensive. With thousands of agents, the trade-off reverses. Exploration becomes cheap, and convergence becomes the hard problem. Your job shifts from “what should I try?” to “how do I synthesize thousands of results?”

High-Leverage Use Patterns
#

Speculative execution on decisions. At every architectural fork, such as “should this be a queue-based system or polling?”, you do not decide, you branch. Two fleets of agents build both options, and you evaluate the results, borrowing the processor idea of speculative execution. This pattern is very useful for situations where you genuinely do not know which approach is better until you have tried it.

Mutation testing at scale. Spin up hundreds of agents making targeted changes to a codebase, each trying a different hypothesis about why a bug exists or how to optimize something. It is like fuzzing, but semantically directed: instead of random inputs, each change probes a specific theory.

Full-stack consistency checking. Have agents simultaneously maintain the contract between every pair of services in your system, constantly verifying that implementations match specs, that error handling is symmetric, and that naming is consistent. Sequential review often misses these checks.

Competitive benchmarking of approaches. For a problem like network latency or caching strategy, you could have 50 agents implement 50 different approaches against the same test harness, and just pick the winner. No reading papers and reasoning about tradeoffs, you settle the question empirically.

Living documentation. Agents continuously reconcile docs, comments, and code. Every pull request triggers agents that check for documentation drift, update runbooks, and surface inconsistencies.

The Harder Problems Cheap Parallelism Creates
#

Synthesis is the bottleneck. If 1,000 agents each produce a pull request, you are back to being the serial bottleneck reviewing them. You need meta-agents whose job is to evaluate and rank the output of other agents, with clear scoring functions.

State and conflict. Agents working in parallel on the same codebase will conflict. You probably want agents working in isolated sandboxes (branches, ephemeral clusters, test environments) with a merge or tournament layer on top.

Task decomposition quality matters more, not less. Bad task specs mean 1,000 agents going confidently in the wrong direction simultaneously. The skill of writing tight, evaluable task specs becomes enormously valuable.

Evaluation functions become critical. “Did the agent succeed?” needs a concrete, automated answer. You cannot manually review 1,000 outputs. That constraint pushes you toward test-driven development.

What This Implies For Infrastructure Work
#

The most compelling application is parallel experimentation on actual infrastructure parameters. Spin up ephemeral environments, have agents try different configurations or scheduling strategies, measure actual performance, then tear the environments down. What makes infrastructure hard is that you normally cannot afford to run 50 experiments simultaneously. With cheap parallel agents managing the scaffolding, that constraint disappears.

The practical limit ends up being compute and money, not ideas, which is a fundamentally different world than the one most engineering workflows were designed for.