JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 43
  • Score
    100M100P100Q90633F
  • License MIT

An orchestrator plugin for OpenCode that implements a four-level orchestration hierarchy (Enterprise → Program → Project → Mission)

Package Exports

  • open-codining

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 executed

Item 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.md

Activating 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 scaffolded

parseElicitationAnswers 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" entry

For 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+ tests

Inside 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
  • R3context.md is 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.