Inside superlite: the philosophy, the gates, and the decisions that shaped it Superlite, an open-source agent orchestration system published on GitHub by developer iha2, is built around a design document of roughly 45 numbered decisions in which every mechanism must be measured, smoke-tested, documented or user-decided before becoming default, with everything else held as an experiment behind a promotion gate. The system splits work across a coordinator session (Opus, medium), seven named subagents including an implementer on Sonnet at medium effort and an implementer-haiku on Haiku at high effort, Python and bash scripts under subagent-driven-development/scripts/, and pre/post tool hooks that enforce rules prompts alone could not hold. Superlite's author reports that prime-then-assign cache sharing became default after sibling agents 2-5 read all 24,876 prime tokens on their first call and wrote zero, and that a 1-hour subagent cache became default after an implementer resumed after seven minutes and read 26,857 cached tokens while the control re-wrote 11,699. Field Notes https://contextfirst.blog/tag/field-notes/ Inside superlite: the philosophy, the gates, and the decisions that shaped it How superlite actually works: the coordinator, scripts, hooks, and agent tiers; the plan → lint → dispatch → checkpoint → review loop; and the gates that enforce it. In the introduction to superlite https://contextfirst.blog/superlite-hand-an-agent-a-spec/ I covered what it is and showed the benchmarks. This post is about the reasoning behind it, and — more usefully — how the system is put together : who does what, what files move, which rules are code rather than prompts, and which decisions I reversed after measuring them. Superlite https://github.com/iha2/superlite?ref=contextfirst.blog 's design document has about 45 numbered decisions. Many of them supersede earlier ones. That's not an accident. It's the main idea. The rule that governs the design The design document opens with one rule for itself: The core design contains only mechanisms that were measured, smoke-tested, documented, or decided by the user. Everything else is an experiment, with the measurement that would promote it. Every idea goes into an experiments table with a promotion gate. "Prime-then-assign cache sharing" became default when siblings 2–5 read all 24,876 prime tokens on their first call and wrote zero. "A 1-hour subagent cache" became default when an implementer resumed after seven minutes and read 26,857 cached tokens while the control re-wrote 11,699. The later slim prime rules + plan header + stable interfaces, no plan body became default when full-plan primes were writing ~26 KB into every dispatch and Sonnet cost was the gap versus superpowers. If something can't pass its gate, it stays an experiment or gets dropped. That rule protected me from my own good ideas more than once. Three equations Everything in superlite https://github.com/iha2/superlite?ref=contextfirst.blog follows from three claims about where time, money and quality come from: - Wall-clock time is set by the critical path. Not by how hard the model thinks. On the first benchmark, both workflows used about the same total model time. One just ran it in a line. - Cost is set by context re-sent per request. Every turn re-sends the conversation. A coordinator with a 130k context taking 80 turns is expensive whatever it's doing. So is shipping a 26 KB shared prime to twenty agents. - Quality is set by an objective oracle plus top-tier review. Tests the agents can't see, plus a reviewer strong enough to find what the tests don't cover. Most of the design is these three claims applied over and over. How a run actually works Philosophy is cheap. Here is the machine. The pieces | Layer | What it is | Job | |---|---|---| | Coordinator | The main session Opus, medium | Sizes the request, writes the plan, dispatches, records rulings. Never writes project code. Never runs raw tests. | | Skills | Injected prompts using-superlite , brainstorming, writing-plans, SDD, … | Tell the coordinator when to call which tools. | | Agents | Seven named subagents in agents/ | Models that design, build, review, or fix. None of them can spawn agents. | | Scripts sl … | Python/bash tools under subagent-driven-development/scripts/ | Anything with a definite answer: lint, route, dispatch, checkpoint, tests, packet, finish. | | Hooks | Pre/Post tool hooks | Enforce rules the prompt alone couldn't hold. Fail open on bad input. | | Run state | .superlite/ in the project | stable.json , primes, pool, metrics, incidents, fix notes, test summary, review packet. | The agents today: | Agent | Model, effort | Job | |---|---|---| | implementer | Sonnet, medium | Builds one task, then stays idle for reuse | | implementer-haiku | Haiku, high | Wave 0 skeleton, and Kind: mechanical tasks off the critical path; stops rather than guesses | | package-reviewer | Sonnet, medium | Reviews a task or package and fixes its own findings | | final-reviewer | Opus, high | Fresh one-turn agent; reads only the review packet; findings with a fix tier; never edits | | fixer-sonnet | Sonnet, medium | Tier 1: cause known, one module | | fixer-sonnet-high | Sonnet, high | Tier 2: cause known, spans modules or a seam | | fixer-opus | Opus, high | Tier 3: cause unknown, or a lower tier failed twice | Control flow A few invariants that hold for the whole loop: 1. Stable work starts before the plan is perfect. lint --stable freezes tasks whose interfaces are clean and prints DISPATCH NOW: … . FIX tasks get patched while agents already run. 2. Consumers don't wait on producers. They build against stubs and the plan's e.g. contract examples. When both sides checkpoint, a script runs the seam check. 3. A checkpoint is not a commit. By default each finished task is saved under refs/superlite/ . Real commits on your branch happen only with /superlite:commit or sl autocommit on . 4. The coordinator decides; scripts compute; agents judge. Ready sets, tiers, seam mismatches, and budgets come from code. Models write code, review meaning, and rule on open choices. 5. No agent spawns agents. Subagents get explicit tool lists without Agent . Fan-out is the coordinator's job. Data the agents see This changed after the early "whole plan as prime" design, and it matters for cost. - Every fresh agent of a tier first reads the same slim prime : implementer rules, plan header, Global constraints, and each stable task's title, Owns, dependencies, and Produces/Consumes lines. No plan body, diagrams, or spec — so nothing in it goes stale while the coordinator is still patching FIX tasks. On one reference plan that was about 7.8 KB against 26.4 KB for the full prime. - It then fetches its own task text live with sl task Tn , which also prints the Produces lines of what that task consumes. Agents learn neighbour names from the current plan, not from a snapshot baked into the prime. - Haiku gets a still smaller mini prime. build prime --prime full keeps the old whole-plan prime for cases that need it. That is the current form of prime-then-assign: shared bytes first so siblings share a cache write , task text second so they don't read a plan the coordinator already rewrote . Modes, not one path /superlite:start or plain language picks a flow from the request: - Regular / architectural — the full plan → parallel build → review loop above. - MVP — plan on a clickable HTML prototype the user assesses, then the orchestrated build. - Feature — research existing code, a feature plan you validate, a prototype in its own worktree to try, then integration with frozen interfaces and seam checks. Human mode has a second gate after you try the prototype. - Debug — root cause first systematic-debugging , then fix-only agents by tier. - Small — inline change, always with a reviewer; no task graph. Same gates and same agent roster; different entry and approval shape. Philosophy 1: rules in code, not in prompts This is the core belief, and I learned it the hard way. Early versions said in the skill text: "the coordinator never edits code" and "never run the test suite in the foreground." The coordinator did both anyway. Not always, but often enough that the build would finish at about 13 minutes and then 10 to 18 more minutes went on the coordinator reviewing, fixing and running raw pytest itself. So those rules became hooks and script exits: | Gate | What it enforces | How | |---|---|---| | The coordinator can't write code | Every change goes to an implementer or fixer; allowed writes are plans, specs, docs, and .superlite/ | block-coordinator-edits hook | | Human mode: nothing builds until you approve | No lint/dispatch/wave0/prime until a real typed reply is on file | hook + sl orchestrator approve | | Tests never block the coordinator | A raw pytest , npm test , go test , … is rewritten into background sl run tests | rewrite-test-runs hook | | No hidden waits on tests | A runner inside until / while or with stdout to /dev/null is denied; wait with sl run tests --wait | same hook + hang probe | | No unsafe kills | No pkill or taskkill /IM , only PIDs the run started | block-unsafe-kill hook | | No agent spawns agents | Subagents get explicit tool lists with no Agent tool | agent definitions | | Every run is measured | Each agent's launch and stop is recorded | capture hooks → metrics.jsonl | How the coordinator guard works is neat: a probe showed that hook inputs from subagents carry an agent id , and the coordinator's don't. One script can tell them apart. There's also a detail I like. The guard is only active while a run marker exists. Originally that marker was the shared prime file, but lint runs before that file exists, and in that gap the coordinator wrote pyproject.toml itself. So the marker became stable.json , which lint writes first alongside prime.md / pool.json . The gap closed. The kill guard has its own story. In one benchmark, the superpowers arm ran taskkill //F //IM python.exe and killed both harness runners mid-run, its own and superlite https://github.com/iha2/superlite?ref=contextfirst.blog 's. Now no run can kill by name. Hooks cost latency, so they're written in bash builtins only where possible. A spawned process costs about 260 ms on my machine. Rewriting the hooks that way took the kill hook from 1.3 s per call to about 340 ms and the coordinator guard from 2.3 s to about 340 ms. And every hook fails open on bad input: a broken guard shouldn't stop a build. Philosophy 2: scripts for anything with a definite answer If a step has one right answer, a script does it. Running tests, checkpointing a task's owned files, checking scope, computing which tasks are ready, scoring idle agents, linting the plan, building the shared prime, checking contracts, collecting the finish summary. None of these need judgment, so none of them get an agent. Agents only do what needs a model: design, write code, review meaning, fix, and rule on choices. That's why superlite https://github.com/iha2/superlite?ref=contextfirst.blog 0.3 removed two agents it used to have. The test-runner Haiku became run tests . The per-wave reviewer became a script-driven seam check plus selective reviews. The coordinator's job shrank to deciding, dispatching and ruling. A related lesson came from token formats. I'd assumed YAML views would save 20–30% of tokens over JSON. I measured it: YAML was smaller than pretty-printed JSON on three of four datasets, but larger than compact JSON on all four, and the absolute difference was a few hundred tokens. So no YAML. What actually saves tokens is a short, purpose-built line like DISPATCH NOW: T2 T4 instead of a 35-field record when the agent needs 8. Philosophy 3: no agent waits Superpowers runs one task at a time by design. Superlite https://github.com/iha2/superlite?ref=contextfirst.blog starts from the opposite rule: ready work starts the moment its dependencies are checkpointed, and nothing queues behind a busy agent. That shows up everywhere: - The task graph sets the width. There's no fixed wave size. Early versions capped waves at five. That was replaced by "the best split, whatever the agent count." One reference run peaked at 18 agents at once; the dispatch cap is tuned separately today it prefers a tighter concurrent set so prime writes don't dominate cost . - Idle agents get reused, busy ones never do. Finished agents wait in an idle pool with their cache warm. A ready task goes to the most relevant idle agent of its own tier. If none is idle, a fresh one starts. - Consumers build against stubs. A task that uses another task's interface doesn't wait for it. It tests against a stub and the producer's e.g. examples. A seam check reruns it against the real producer once both sides checkpoint. - Plans don't block agents. I'll come back to this under the gates. - Every test run is in the background, with one wait right before finish. A hang probe reports SUSPECT HANG from flat output/CPU/children; by default it does not kill. The gates Superlite https://github.com/iha2/superlite?ref=contextfirst.blog 's gates each exist because of a specific failure. The table above is the enforcement layer. Below is why each kind of gate is shaped the way it is. Gate 1: the human gate once Superpowers' stops were its slowest part, so superlite https://github.com/iha2/superlite?ref=contextfirst.blog has one approval gate, then no stops except for destructive, outward-facing, or security-sensitive actions. Before that gate, superlite https://github.com/iha2/superlite?ref=contextfirst.blog sizes the request: - Trivial a typo, a rename : just do it. - Bounded a change to a flow that already exists in the repo : a short design in chat, one yes. - Architectural a new project or subsystem : one batch of up to four questions, one design-and-plan document, one yes. - Spike "is it possible to..." : say what it'll try in two sentences, then try it. Questions are always batched. Never one per message. Who orchestrates is asked in that same batch or skipped when the request already settles it: "decide yourself", away, headless → AI . Then there's the choice of who orchestrates . - Human orchestrator. You get a plain-language review plan with diagrams. Nothing is linted, dispatched, or sent to an agent until a real typed reply approves it — a hook records replies, and sl orchestrator approve refuses to proceed without one newer than the review file. After that, scope changes become rulings, not more questions. Feature mode adds one planned second stop: trying the prototype. - AI orchestrator. Never stops for plan approval. Every choice it would have asked about becomes a ruling: Ruling: