Inspiration π‘
A coding agent works well when one task fits inside one conversation. Larger projects are different. Research, frontend work, backend work, testing, and review can happen in parallel, but a single agent has to do them one after another. Starting more agents is easy; making them work as a team is not.
The starter platform already gave us a browser UI, a Fastify control plane, and Codex running inside disposable containers. What it did not have was a way to coordinate several agents, show how their work fits together, or carry a useful method from one session into the next.
We built that missing continuity layer. It helps agents work together during a run, then turns validated experience into skills that future runs can reuse.
What it does β¨
Launchpad supports both standalone agents and leader-led teams. For a complex task, the leader makes a dependency-aware plan, dispatches specialists, and joins their results. The user can watch each trajectory and steer the active run.
1. Coordinate a team
- The leader creates named subtasks with explicit dependencies. Independent work starts together; downstream work waits for its inputs.
- Each worker has an isolated execution context, while the team shares a common workspace for artifacts, messages, and installed skills.
- Coding workers return bounded Git contributions instead of editing the same project state blindly.
- The interface shows the leader, workers, mission phase, plans, commands, file changes, tool calls, messages, and final result in one timeline.
2. Communicate without creating chaos
Three delivery modes make urgency and cost explicit. quiet waits for the
recipient's next turn and costs no extra model call. talk joins an active
turn, or queues if the recipient is idle. wakeup starts a new turn immediately
and spends from the team's follow-up budget.
The sender comes from a scoped token, not a name inside the message. Messages are journaled before delivery so pending work survives a restart. One budget covers the leader and every worker. The shared token budget is enforced, not just displayed. One ledger records input and output tokens across the leader and workers. Once its configured ceiling is reached, the middleware starts no further model request.
Wakeups have a separate follow-up allowance because each one creates another model turn. An exhausted wakeup is refused with a visible receipt rather than silently dropped or allowed to create runaway agent conversations.
3. Reuse knowledge across sessions
An agent can turn a proven workflow into a skill and publish a validated, versioned package to the persistent Skill Hub. Each entry records its origin, evidence, and the version it supersedes. Later agents can install it into the team's shared workspace.
Before an agent starts, a deterministic router ranks matching skills, rejects unsafe provenance, and installs a high-confidence match. Low-confidence results remain a shortlist. The UI shows what was selected, where it was installed, and why.
Overall Flow π
- A user opens a project, chooses a standalone agent or a leader, and sends a task.
- The leader produces a dependency graph. The middleware validates it before any worker starts.
- The scheduler launches independent workers as a parallel wave. Every worker receives scoped MCP tools, its own runtime context, and access to the common workspace.
- Workers exchange bounded messages, publish artifacts, and return results or Git contributions. The user can steer the live trajectory at any time.
- The leader evaluates the work, integrates verified contributions, and returns one answer.
- A useful method can be validated and published as a skill. A future task can have that skill selected and installed before its agents begin.

How we built it π οΈ
The project is TypeScript end to end: Fastify and Zod on the control plane, React and Vite in the browser, Codex CLI inside Docker for the agent runtime, and a generated MCP server injected into every container.
The trusted control plane owns identity, delivery, persistence, budgets, and validation. Agents still decide what to say and build, but they cannot decide who they are or silently widen their scope. Real model-provider credentials stay outside the containers. Each container receives a per-run token and sends model traffic through our egress proxy, which gives us attribution and a trace without exposing the provider key.
Run events and team messages are persisted as append-only records. That same event stream powers the browser timeline, token and cost estimates, recovery, and the evidence used to debug a failed run. Skills live in a separate persistent store outside any disposable runtime, with version and provenance metadata beside the package.
The trace is a connected execution record rather than a collection of unrelated logs. Each event carries its sequence, run and agent identity, span relationship, status, timing, error, usage, and safely bounded input or output summary.
Messages, tool calls, workspace changes, Git contributions, and integration decisions retain their run or member relationship. This lets us follow one user task from the browser, through the control plane, into each runtime and back.
Reliability and safety π
Everything a run did stays queryable. Run events, agent-to-agent messages, the worker tree, and published artifacts each have their own read endpoint, and the browser timeline is rendered from those same records rather than a separate display copy. One event stream drives the timeline, the usage numbers, restart recovery, and the evidence used to debug a failure, so what the interface shows is what the system actually acted on.
Spend is visible while it happens. Every run reports input, output, and total tokens alongside an estimated cost from published provider rates. Reasoning tokens are subtracted from the visible output count, because providers bill them as output even though they are not part of what the agent produced. Token limits and cost estimates have different authority. The token ledger may stop new calls at a configured ceiling. Displayed dollar cost is an estimate from provider rates and never becomes an automatic policy decision.
Recovery restores authoritative state instead of guessing success. Pending delivery is reconstructed from the journal. A conflicting contribution leaves the canonical Git head unchanged, while restart recovery reconciles durable state without rerunning agents. Ambiguous failures remain visible as rejected, cancelled, pending, or unavailable. The middleware does not convert a missing receipt, unreadable trace, or interrupted write into an empty result or successful run.
A worker that stops making progress gets stopped. A trajectory monitor watches each worker and can end the attempt itself rather than only recording it. It halts on no evidence of progress, a repeated action signature, oscillation between states, drift outside the declared scope, a protected-path violation, consumer incompatibility, or a runtime step limit. When it fires, the runtime is cancelled and a fault record is written with the evidence behind the decision.
Secrets are removed before anything is written. Redaction sits on the persistence path rather than running as a cleanup pass afterwards: secret-shaped fields are replaced and long strings are bounded before an event reaches disk. The model proxy, event log, trajectory log, and container runner all share the same redactor, so the trace, a screenshot of the timeline, and an exported log are covered by one rule instead of three.
Challenges we ran into π§±
The most useful runtime events were being discarded
The baseline parser kept only four Codex event types and dropped reasoning, commands, file changes, and tool calls. We first had to capture and persist that stream. Once it existed, the same trace became the basis for the multi-agent timeline, model-call attribution, usage reporting, and failure analysis.
We were not on the model-call path
At first, each container held the real provider credential and called the model directly. An external monitor could not reliably observe or control that path. We changed the generated runtime configuration to call our egress proxy with a scoped token. This kept the real key in the control plane and made each request attributable to its run and agent.
Multi-agent bugs hid behind single-agent tests
One shared React mounted reference leaked a polling loop every time the user
navigated between agents. In a real team run we measured 17 requests in five
seconds across two stale parent runs and 3,790 DOM mutations. After giving each
effect its own cancellation state, polling stayed on one parent at a steady
one-second interval and the same observation produced 34 mutations.
Self-healing could not be allowed to grade itself
We built an experimental bounded repair path for coding failures. It freezes a Git checkpoint, performs one diagnosis, and evaluates three isolated candidates: a control, a context patch, and a strategy patch.
The candidate does not decide whether it succeeded. Protected gates, fixtures, and mutants run from a verifier outside its workspace. Candidate-authored tests are supplementary evidence, and the control candidate wins an exact tie.
We also recorded Project-scoped evolution history. A fully identical, audited failure may prune a repair already proven useless; an analogous failure can supply bounded context cues but cannot change tools, authority, or expected outcomes.
Integration showed that this logic sat too close to normal coordination. Ambiguous Git ownership and an event-flush race affected ordinary execution, while evolution reconciliation still shared startup work with the production path.
We kept healing disabled by default and treated that result as an architectural lesson: adaptation should observe a reliable execution core from outside it, not become another authority inside every active run.
Accomplishments that we're proud of π
- A working leader-worker system that supports parallel plans, live steering, agent-to-agent communication, shared artifacts, and verified code return.
- One readable trajectory across the leader and every worker, backed by real runtime events rather than invented progress states.
- A persistent, versioned Skill Hub plus middleware-owned selection and installation before a run starts.
- Explicit degraded and denial paths that keep the run observable instead of crashing or pretending that nothing happened.
- The original standalone lifecycle and Playground remain available alongside the new multi-agent path.
- An experimental, end-to-end bounded-repair fixture with isolated candidate workspaces, independent verification, deterministic fallback, restart-safe lineage, and conservative exact-repeat pruning.
What we learned π
Parallel work is not coordination. Starting several containers is easy. The hard part is deciding what can run together, passing results to downstream tasks, and integrating contributions without letting workers overwrite one another. Without that, a multi-agent system is just several solo agents running at once.
Agent communication is execution, not chat. A message can interrupt another
agent and start a model turn. That is why quiet, talk, and wakeup need
different semantics, and why delivery needs receipts, budgets, and visible
failure states.
A shared directory does not make a team. Files carry artifacts, not identity, responsibility, or trust. The system still needs token-scoped senders, bounded Git contributions, and provenance showing where a result came from.
Team memory lives on two timescales. During a run, the journal keeps messages and recovery state alive across process failures. Across runs, the Skill Hub preserves validated methods for future agents. Both are middleware responsibilities; a prompt cannot guarantee either one.
The system being improved cannot weaken its own judge. Candidate execution and verification need separate authority. Future verifier changes must be evaluated against immutable evidence rather than promoted because they approve more candidates.
Evolution belongs outside the reliable run loop. A normal run should emit durable execution facts and finish independently. Candidate generation, shadow evaluation, and promotion can then fail without changing that result.
What's next π
Decoupled evolution: freeze the working multi-agent core and let it emit append-only execution facts. An asynchronous observer can mine failures and evaluate candidate harness versions without delaying an active run.
Shadow tournaments: compare each candidate with a frozen baseline in isolated workspaces, budgets, and cancellation scopes. Initially, a candidate can produce evidence but cannot promote itself.
Next-run-only promotion: assign an immutable harness version when a run begins. A manually approved version can affect the next run, but never mutate prompts, policies, workers, or verification during an admitted run.
Evolving verification: maintain verifier history separately from execution and harness history. Repair a verifier only from versioned disagreements with an immutable oracle, with independent regression evidence and rollback.
Meta-agent: analyze accumulated trajectories, failure families, and verifier mismatches to propose small harness improvements rather than rewriting the system wholesale.
Built With
- docker
- fastify
- jsonl
- node.js
- react
- typescript
- vite
- zod
Log in or sign up for Devpost to join the conversation.