open-codining
v1.0.6
Published
An orchestrator plugin for OpenCode that implements a four-level orchestration hierarchy (Enterprise → Program → Project → Mission)
Downloads
1,214
Maintainers
Readme
Open-Codining — Multi-Level Orchestration Platform
Fork of opencode-orchestrator (MIT) extended into an AI Delivery Platform: a four-level orchestration hierarchy (Enterprise → Program → Project → Mission) driven by formalized specs and backlogs, with evidence-based verification at every level. The original engine — Commander / Planner / Worker / Reviewer, MVCC
todo.md, the autonomous mission loop — is untouched. Everything here is additive.
The hierarchy
EnterpriseCommander → portfolio, capacity budget, allocation strategies
↓ delegate_task
ProgramCommander → projects, priorities, inter-project dependencies
↓ delegate_task
ProjectCommander → backlog items, spec injection, mission delegation
↓ delegate_task
Commander (core) → the original autonomous mission engine — untouched
↓
Planner / Worker / Reviewer (core)Each level only knows the level directly below. Level skipping is forbidden by prompt and by design.
Commander Gate
A level is triggered through exactly two doors:
| Level | Hierarchical trigger | User trigger |
|---|---|---|
| Enterprise | — (top) | select EnterpriseCommander + /task or any prompt |
| Program | EnterpriseCommander | select ProgramCommander + /task or any prompt |
| Project | ProgramCommander | select ProjectCommander + /task or any prompt |
| Mission | ProjectCommander | select Commander + /task or any prompt |
On any other agent the plugin is fully transparent: no loop, no prompt injection, no message transformation, no notification — default OpenCode behavior, as if the plugin were not installed.
Spec & Backlog Driven mode
No work starts from a free-form prompt at the Project level. Work is driven by two files — the mode activates by their presence (absence = legacy core behavior, untouched):
.opencode/
├── spec.md stable project spec (scope, constraints, definition of done)
├── backlog.md prioritized items: B001, B002… (priority, size, status, deps, acceptance criteria)
└── backlog-item-active.md the item currently being executedItem lifecycle (one at a time): select (eligibility = deps [x], priority order, age, size) →
inject (spec + acceptance criteria prepended to context.md, read by every core agent) →
execute (one core mission; every acceptance criterion becomes a verifiable leaf sub-task in todo.md) →
close (refused until the core verification passes) → next item.
Multi-project / multi-program storage (swap model)
.opencode/
├── enterprise.md portfolio: budget, strategy, PGM-xxx programs
├── programs/<PGM-ID>/
│ ├── program.md projects of the program: PRJ-xxx
│ └── projects/<PRJ-ID>/
│ ├── spec.md
│ └── backlog.mdActivating a program installs its program.md + projects/ tree as the working copies;
activating a project installs its spec.md + backlog.md the same way. The lower loops run
unchanged on the working copies. Closing or failing syncs everything back — including
mid-flight state, nothing is ever lost.
Capacity allocation (Enterprise)
enterprise.md header: - Budget de capacité : N and - Stratégie : proportional | equal | priority-first.
The allocation engine is pure and deterministic: paused program → 0 slots · no eligible items → 0 slots (redistributed) · every active candidate gets ≥ 1 slot (anti-famine) · slots never exceed a program's eligible items · ties broken by priority then file order.
Level tools (deterministic state transitions)
The LLM decides when; tested code decides what happens. Closing tools are refused without evidence (R7):
an item cannot close until the core mission verification passes; a project cannot close until every
item is [x]; a program cannot close until every project is [x].
| Level | Tools |
|---|---|
| Project | backlog_start_item · backlog_verify_item · backlog_close_item · backlog_fail_item · backlog_suspend_item · backlog_resume_item · backlog_status |
| Program | program_start_project · program_verify_project · program_close_project · program_fail_project · program_status |
| Enterprise | enterprise_start_program · enterprise_verify_program · enterprise_close_program · enterprise_fail_program · enterprise_status |
| Transverse | plan_project (élicitation guidée → scaffold) · scaffold_project · portfolio_report · validate_workspace (+repair) · record_escalation · resolve_escalation · web_console_info |
Guided elicitation → scaffold (BMAD borrowing B1)
The most valuable BMAD idea, placed at the right spot: the human stays in the loop ONLY at the upstream planning stage. A 3-line brief is enough:
brief → plan_project → structured questionnaire (measurable objective,
in/out scope, constraints, risks, proposed item breakdown with criteria)
→ the Planner asks the human ONCE → human validates the breakdown
→ plan_project(answers) → VALIDATED spec.md + backlog.md scaffoldedparseElicitationAnswers is a pure parser+validator: ids B001+ unique,
priorities P1-P4, sizes S/M/L/XL, non-empty verifiable acceptance criteria,
internal dependencies resolved — or a refusal listing every gap (never a
half-valid input). /plan routes to this workflow when no backlog exists
(legacy mission task plan otherwise); the Program/Enterprise commanders use
it with target_dir instead of hand-drafting files. Same anti-overwrite
guard as scaffold_project.
Mission completion record (BMAD borrowing B2)
Every mission contract requires a final ## Compte-rendu section in
todo.md (- Fichiers : / - Notes : / - Suivi :). It is a soft
contract: absence raises a verification warning, never an R7 lock (free
text is not mechanical evidence). On close, the summary is journaled
(ITEM LIVRÉ — n fichier(s), notes: …) and archived with the item; project
closes roll the records up into the program journal
(Comptes-rendus n/m — B001: …). Exposed in portfolio_report,
/api/mission and the Mission view.
Structured escalations & HALT (BMAD borrowing B3)
Every level prompt carries explicit HALT conditions (contradictory spec,
broken external dependency, same error after 3 attempts, uncovered
destructive action). record_escalation writes a structured block (context,
attempts, 2-3 documented options, expected decision) to the level journal;
resolve_escalation records the human decision. Pending escalations surface
in backlog_verify_item, the Backlog view and portfolio_report.
Level journals — lossless rotation
Every state file carries a ## Journal of dated entries. Beyond 200
entries, the oldest are archived to .opencode/archive/journals/ (down to
150 kept) — MVCC split, content outside the journal stays byte-intact.
Real parallelism (opt-in) — execution slots
Add - Parallélisme : activé to enterprise.md (git workspaces only) and the
capacity budget becomes a REAL constraint: up to N backlog items run
simultaneously, each in its own execution slot — a git worktree placed
outside the workspace ($TMPDIR/orchestrator-slots/<hash>/<slotId>, branch
orchestrator/<slotId>, node_modules symlinked). No swap: every active
program/project is driven directly on its STORED files, and the delegations
carry the exact paths.
Closing an item stacks four mechanical locks: the slot's todo.md passes
the core verification (R7) → the work is committed → the MAIN workspace is
git-clean (a mission that escaped its slot blocks everything, by code) → the
slot branch merges sequentially. A merge conflict keeps the slot
(conflict state) with resolution instructions; failures keep the branch for
post-mortem. The §8.2 budget is enforced portfolio-wide: item starts beyond
it are refused wherever they come from.
| Level | Parallel tools |
|---|---|
| Project | parallel_start_item · parallel_verify_items · parallel_close_item · parallel_fail_item |
| Program | program_start_projects_parallel · program_verify_projects_parallel · program_close_project_parallel · program_fail_project_parallel |
| Enterprise | enterprise_start_programs_parallel · enterprise_close_program_parallel · enterprise_fail_program_parallel |
Crash recovery: validate_workspace reconciles slots.json ⇄ git worktrees ⇄
[/] markers (SLOT_WORKTREE_MISSING, UNREGISTERED_WORKTREE,
ITEM_WITHOUT_SLOT), and repair=true resets items to [ ], prunes and
cleans — losslessly. Without the flag, everything behaves exactly as before
(time-multiplexing, R5).
Pull discovery — grep the steering files, never read them whole (v5)
Steering corpora are tiny for a machine but expensive for a context
window. So agents follow a pull discipline instead of read mandates:
grep the steering files of YOUR role with the terms of YOUR task (item
id, criterion keywords), then read ONLY the matched line ranges — using
the host's native grep/read tools, nothing to install.
A generated charter (~345 stable tokens) teaches every agent the file
anatomy with its greppable anchors (### B007 items and their field
lines, ## Contraintes spec sections, ## Journal dated entries, status
markers) plus a "where to look" element→file map. It is generated from
the SAME constants the parsers use — a sync test fails if any anchor
diverges. The injected context block now carries the item's acceptance
criteria VERBATIM (the contract, never summarized) + the charter: 1241 →
452 tokens per turn per agent on the reference fixture; a typical spec
access drops from a 4260-token cat to ~935 tokens (grep + one ranged
section read).
An optional mechanical guard turns the discipline into behavior: a
whole-file read of a steering file above 150 lines is answered with the
file's outline and the grep-then-range reminder instead of executing.
Fail-open by construction, exempting context.md/todo.md (core
mandate), inert outside spec/backlog mode. Configure it in
.opencode/orchestrator.jsonc:
{ "steering": { "readGuard": true, "lineThreshold": 150 } }ORCHESTRATOR_STEERING_GUARD=0 disables it without touching the file.
Recovery — every level, the same principle
DECOMPOSE → RE-PLAN → ESCALATE. Never give up silently.
Level 3 at the Enterprise is ASK HUMAN: a structured summary (context, attempts per level,
2–3 documented options, expected decision) is written to enterprise.md and the chain waits.
The human is the last resort, nothing else.
Status markers — shared by every file of the hierarchy
[ ] pending · [/] in progress · [x] verified complete · [-] failed · [~] suspended
Every state file (enterprise.md, program.md, project.md, backlog.md) is MVCC-managed
(optimistic versioning + mutex + atomic rename), same guarantees as the core todo.md.
Installation
npm install open-codining # once published — the postinstall registers
# "open-codining" in your opencode config and
# MIGRATES any legacy "opencode-orchestrator" entryFor a local/unpublished build, reference the plugin by path in the
project config (.opencode/opencode.jsonc):
{ "plugin": ["/abs/path/to/node_modules/open-codining/dist/index.js"] }Uninstalling (npm uninstall) cleans both the fork and legacy entries.
Quick start
npm install # from this repo
npm run build # backend bundle + Vite web console
npm test # 920+ testsInside OpenCode, select the Commander of the level you want and prompt:
# Single mission (core, unchanged)
[Commander] /task "Implement JWT auth"
# No backlog yet? Guided elicitation from a 3-line brief
[Planner] /plan "A small task-management API, token auth, Docker"
# One project driven by a spec + backlog
[ProjectCommander] "Deliver the backlog"
# A portfolio
[EnterpriseCommander] "Deliver the portfolio"Non-regression guarantees
- R1 — zero modification of the core engine's behavior; all additions are layered
- R3 —
context.mdis enriched (delimited block), never replaced; eject restores it byte-for-byte - R5 — without
spec.md/backlog.md, the system behaves exactly like the original plugin - R6 — every level state file is MVCC-managed
- R7 — only evidence closes anything, at every level
- R8 — Commander Gate: full plugin transparency on non-Commander agents
Web Console
Une console web locale pour piloter l'orchestrateur sans la TUI : prompts et
/task vers les Commanders, suivi des backlogs, du portefeuille, des slots
parallèles, des escalades et des rapports — en temps réel (SSE).
Activation (opt-in, désactivée par défaut)
Deux voies, vérifiées contre opencode 1.16 réel :
// .opencode/orchestrator.jsonc — fichier DÉDIÉ (recommandé)
{ "webConsole": { "enabled": true, "port": 4096 } }ORCHESTRATOR_WEB_CONSOLE=1 opencode # ou par env ; port : ORCHESTRATOR_WEB_PORT⚠️ Ne mets JAMAIS la clé dans .opencode/opencode.jsonc : opencode valide
strictement sa config et refuse de démarrer (Unrecognized key).
Précédence : env (0 désactive même si le fichier active) > fichier dédié >
défauts.
Récupérer le token (la TUI écrase le log)
Au démarrage, le plugin écrit un fichier d'accès éphémère
.opencode/console-access.json (0600) contenant connectUrl — l'URL prête à
cliquer (http://127.0.0.1:4096/#token=…). Il est supprimé dès la première
connexion authentifiée avec ce token, ou à l'arrêt de la console ; un
fichier orphelin d'un crash est écrasé au démarrage suivant. En cours de
session, l'outil web_console_info redonne l'URL+token dans le chat.
Sécurité : bind 127.0.0.1 uniquement, token bearer éphémère exigé sur toute
l'API ; aucune panne de console ne peut affecter le plugin.
Multi-workspace (plugin global, plusieurs répertoires)
La console est un singleton par machine : la première instance opencode la
démarre ; chaque instance suivante s'y rattache automatiquement (bridge
local sur port éphémère) au lieu d'ouvrir une deuxième UI. Toute interaction
est identifiée par workspace (?workspace=) : le sélecteur de la sidebar
bascule l'intégralité des vues ; les lectures et actions de niveau opèrent
directement sur les fichiers du workspace ciblé, les prompts/commandes sont
relayés au process opencode qui le possède (son propre client SDK). Demande
web_console_info dans le chat pour retrouver l'URL et le token.
Vues
| Vue | Contenu |
|---|---|
| Chat & Commande | sessions, pilules d'agent, prompt libre (boucle de niveau) ou /task, abort, approbations (questions de l'agent et autorisations d'outils — bannière bloquante avec réponse en un clic), historique de prompts re-lançable, rendu markdown, notifications navigateur |
| Mission | todo.md + vérification core + compte-rendu de mission (B2, warning doux si absent) |
| Backlog | items + actions de cycle de vie, alerte S5, escalades EN ATTENTE, validation/réparation, journal ; sans backlog : formulaire d'élicitation guidée (brief → questionnaire → scaffold) |
| Portefeuille | enterprise (stratégie, jauge de capacité, allocation), programmes, projets |
| Slots | exécution parallèle en direct (todo du worktree, commits, conflits), clôture verrouillée R7 |
| Rapport | portfolio_report markdown, maintenance |
API (mapping 1-1 du core)
Lecture : /api/overview, /api/mission, /api/backlog?path=,
/api/portfolio, /api/slots, /api/journal?file=, /api/report.
Actions opencode : /api/prompt, /api/command, /api/abort,
/api/sessions, /api/pending (questions+autorisations en attente),
/api/question/:id/reply|reject, /api/permission/:id/reply. Actions de niveau : POST /api/level/<action> (34 actions,
mêmes arguments et mêmes refus que les outils LLM, dont plan_project —
un refus core répond 409 avec son libellé exact). Flux : /api/events (SSE, ?token=, rattrapage Last-Event-ID après reconnexion).
Les fichiers .opencode/*.md restent l'unique source de vérité ;
.opencode/console.db (SQLite) ne contient que des données d'interface
jetables. Dev front : npm run dev:web (proxy vers 127.0.0.1:4096).
License
MIT — original work by agnusdei1207.
