The Story
Workwarrior started as a personal system. It became a project when the personal system got complicated enough that it needed to be engineered. Here's how we got here.
The Problem It Solved
The immediate problem was context bleeding. Work tasks showing up in personal task views. Personal time tracking mixing with client billable hours. Journal entries about one project surfacing when searching another. These aren't edge cases — they happen the moment you have more than one serious work context in your life.
The fix — profile isolation — sounds obvious in retrospect. One directory per context.
Environment variables that all tools read. p-work to switch in, p-personal
to switch out. No tool knows the others exist. No tool knows Workwarrior exists.
That's the core. Everything else is a consequence of having the core right.
Why Not Build New Tools
TaskWarrior has a user-defined attributes system sophisticated enough to model almost any data schema. Hledger implements a 50-year-old accounting standard that hasn't needed reinventing. JRNL handles plain text journals with the right amount of structure. These tools exist because people built them carefully over years and released them.
Building replacements would mean rebuilding all that and maintaining it. Wrapping means the tools stay excellent while the integration layer — the only part that didn't exist — gets built once.
The wrapper needs to stay thin. When it gets thick, it's usually because a tool needed patching rather than wrapping. Those cases get contributed upstream when possible.
The Heuristic Engine
The natural language command layer started as a proof of concept: could you type something like "add a task to review the budget due friday" and have it work without an LLM?
The answer turned out to be: yes, for most things, if you compile enough rules. 627 regex patterns across 19 command domains, with 6 phrasing variations per command. The compiler scans the codebase for command definitions, generates patterns, validates them against a synthetic corpus, and writes the output.
The key design decision was the fallback order: heuristics first, always. AI is optional and opt-in. If you never configure an LLM, the heuristic engine handles everything it can handle, and the things it can't handle fail loudly rather than silently sending data to a third-party API.
The self-improvement loop came later: every CMD submission is logged. Run
ww compile-heuristics --digest and it reads that log, finds the AI translations
that worked, and converts them into new heuristic rules. Over time, the AI fallback handles
less. The heuristic engine handles more.
The Browser UI
The browser UI was the feature that surprised us. The assumption going in was that terminal people would want to stay in the terminal. The assumption turned out to be wrong — or at least incomplete. Having a dashboard that shows tasks, time, journal, and ledger simultaneously, that accepts natural language commands, that updates in real time when you switch profiles from the CLI, that runs locally on a standard library Python server — that turned out to be more useful than expected.
The constraint that made it work: no npm. No build step. No external dependencies. Python 3
stdlib only. If someone can run Python, they can run the browser UI. The static files serve
directly from disk. The SSE endpoint holds open connections for real-time updates.
The REST API is 20 endpoints over a ThreadingHTTPServer.
Security boundary: an ALLOWED_SUBCOMMANDS frozenset validates every POST /cmd
request. No sh -c. No eval. First token must be a known ww subcommand. A browser
UI that executes arbitrary shell commands is a remote code execution vulnerability. This one doesn't.
The System
The project developed an internal coordination model — a set of agent roles, gate contracts, and a fragility register — that turned out to be the right way to manage a bash codebase with 24 library files and a sync engine that touches bidirectional external state.
The sync engine (10 files, HIGH fragility classification) is the most dangerous part of the codebase. Getting it wrong means data loss in both TaskWarrior and GitHub. Every change to those files requires an extended risk brief, explicit write scope, and Verifier sign-off before merge. Not because we're bureaucratic — because the failure modes are irreversible.
That same agent model ships as ww mcp install — an MCP server that makes the
Workwarrior control plane available to any AI agent. The model that builds Workwarrior
is the same model you can use to manage your own projects.
Where It's Going
The extension system and weapons roadmap (Bat, Fire, Slingshot) represent the next phase. The core is stable. The integration layer is mature. The next work is at the edges: more weapons, a richer extension registry, better tooling for people who want to build services on top of the Workwarrior architecture.
The standard — ww-standard on GitHub — is the canonical technical specification
for what Workwarrior is and how it works. When WW ships to users, it ships with references
to that standard. The standard is open. The architecture is open. The whole thing is as
open source as it gets.