Skip to content
Back to work

Orchestra OSS: an agent task-handoff boardOrchestra OSS:把一个功能拆成任务、派给 agent 的看板

Year
2026
Status
Paused
Outcome
A feature idea in, a task graph and Codex-ready handoff commands out — behind them, four executor stubs.

Four executor adapters, a three-stage state machine, a full handoff serializer — and not one process ever launched. That is the shape of this repo.

It is the public extract of a board I built inside another project, DODGE AGENT, which has its own entry on this site; that repo's orchestra page still imports a board component I never committed. The premise: a feature shouldn't start with writing issues. You start with a vague notion, the tool turns it into a task graph with owners and dependencies, and the ready tasks come out as commands you hand off.

Planning is templates, not a model — three of them, five tasks each, filled from the feature title and one problem sentence you type. The handoff packet is the part worth keeping. commander.ts assembles objective, acceptance criteria, context, constraints and operating rules, renders a command from a template like codex exec "{title}: {summary}", splits it into command plus args, and serializes the packet to JSON. Above that sit multiple boards, a cross-board dispatch queue, and a Chinese/English toggle. A clean clone still builds.

The last step is the missing one. All four adapters declare supportsLive: false, so the preview / armed / live selector never reaches live — it returns unsupported_live_mode every time. The stub says so in its own stderr: No process was launched. Replace this stub with a real spawn/exec implementation. No network calls anywhere in src/; everything lives in browser storage. The last section of the guide puts the boundary in my own words: a finished prototype plus the interface layer that would sit in front of real execution.

Two commits the evening of March 6, 2026, thirty-nine on March 7, four on the morning of March 8. The last two were a pivot — board to chat-first, with a clarification step that turns out to be hardcoded rules: check which fields are empty, ask up to three canned questions, write the answers back into the form. Enough momentum to notice that a board alone wasn't the product, not enough to act on it.

Underneath: 6,036 lines of TypeScript, 4,424 of them in one component holding 48 useState hooks. package.json declares lint: eslint src, but the repo ships no eslint config, so the one check I wrote down does not run. No tests, no CI. For three days I kept adding surface, because surface is fast and visible. An execution engine is neither.