opencode-orchestrator-uni 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -6
- package/README.ru.md +352 -0
- package/agents/en/arbiter.md +38 -0
- package/agents/en/empiric.md +84 -0
- package/agents/en/factcheck.md +43 -0
- package/agents/en/fix-runner.md +59 -0
- package/agents/en/invariant.md +79 -0
- package/agents/en/meta.md +48 -0
- package/agents/en/orchestrator.md +55 -0
- package/agents/en/redteam.md +57 -0
- package/docs/en/call-mechanics.md +235 -0
- package/docs/en/instruction-other-session.md +81 -0
- package/docs/en/process-ready-loop.md +66 -0
- package/docs/en/root-runbook.md +57 -0
- package/docs/{call-mechanics.md → ru/call-mechanics.md} +1 -1
- package/docs/{root-runbook.md → ru/root-runbook.md} +1 -1
- package/index.ts +126 -17
- package/package.json +3 -1
- /package/agents/{arbiter.md → ru/arbiter.md} +0 -0
- /package/agents/{empiric.md → ru/empiric.md} +0 -0
- /package/agents/{factcheck.md → ru/factcheck.md} +0 -0
- /package/agents/{fix-runner.md → ru/fix-runner.md} +0 -0
- /package/agents/{invariant.md → ru/invariant.md} +0 -0
- /package/agents/{meta.md → ru/meta.md} +0 -0
- /package/agents/{orchestrator.md → ru/orchestrator.md} +0 -0
- /package/agents/{redteam.md → ru/redteam.md} +0 -0
- /package/docs/{instruction-other-session.md → ru/instruction-other-session.md} +0 -0
- /package/docs/{process-ready-loop.md → ru/process-ready-loop.md} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# opencode-orchestrator-uni
|
|
2
2
|
|
|
3
|
+
**English** · [Русский](./README.ru.md)
|
|
4
|
+
|
|
3
5
|
A native [OpenCode V2](https://opencode.ai/v2/docs/build/plugins) package plugin that
|
|
4
6
|
ships the **orchestrator agent kit**:
|
|
5
7
|
|
|
@@ -38,10 +40,10 @@ All agents ship **without a model**: models are deployment configuration (see
|
|
|
38
40
|
[Models](#models)). Definitions live in [`agents/`](./agents) as plain Markdown agent
|
|
39
41
|
files and are parsed at setup time — the files are the single source of truth.
|
|
40
42
|
|
|
41
|
-
The `audit-kit` reference points at this package's `docs
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`<reference path>/call-mechanics.md`.
|
|
43
|
+
The `audit-kit` reference points at this package's per-locale `docs/<locale>/`
|
|
44
|
+
directory (see [Locale](#locale)). OpenCode lists it in session context as an
|
|
45
|
+
additional local directory, so the orchestrator (and any other agent) can read
|
|
46
|
+
the process documents directly, for example `<reference path>/call-mechanics.md`.
|
|
45
47
|
|
|
46
48
|
The plugin also registers three deterministic, **read-only** tools in the `orch_uni`
|
|
47
49
|
namespace — see [Tools](#tools).
|
|
@@ -194,6 +196,34 @@ Agent definitions carry no `model`; models are configured on the plugin entry in
|
|
|
194
196
|
- An `agents` config entry or a local Markdown agent file that defines its own
|
|
195
197
|
model still wins — configuration is applied after package plugins.
|
|
196
198
|
|
|
199
|
+
## Locale
|
|
200
|
+
|
|
201
|
+
Agent definitions and process documents ship per locale — `agents/<locale>/`
|
|
202
|
+
and `docs/<locale>/`; currently `ru` and `en` (the English content is a
|
|
203
|
+
translation of the Russian originals). The kit picks one locale in this order:
|
|
204
|
+
|
|
205
|
+
1. `options.locale` (`"ru"` or `"en"`; full tags such as `"ru-RU"` are accepted);
|
|
206
|
+
2. auto-detection: `LC_ALL` / `LC_MESSAGES` / `LANG`, then the runtime's Intl
|
|
207
|
+
locale (the OS setting);
|
|
208
|
+
3. the default: `en`.
|
|
209
|
+
|
|
210
|
+
```jsonc
|
|
211
|
+
{
|
|
212
|
+
"$schema": "https://opencode.ai/config.json",
|
|
213
|
+
"plugins": [
|
|
214
|
+
{
|
|
215
|
+
"package": "opencode-orchestrator-uni",
|
|
216
|
+
"options": { "locale": "ru", "model": "deepseek/deepseek-flash" }
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
A requested locale that ships no content falls back to the default locale and is
|
|
223
|
+
reported with a warning in the plugin log. Both locales register the same agents
|
|
224
|
+
under the same ids — switching the locale only changes the language of the
|
|
225
|
+
prompts, the process documents and the reference description.
|
|
226
|
+
|
|
197
227
|
## Requirements
|
|
198
228
|
|
|
199
229
|
- **OpenCode 2.x** with the V2 plugin API (the `plugins` config field). V1's plugin
|
|
@@ -274,7 +304,7 @@ npm run lint # biome check . (lint + format + import order; read-only)
|
|
|
274
304
|
npm run lint:fix # biome check --write . (applies safe fixes)
|
|
275
305
|
```
|
|
276
306
|
|
|
277
|
-
`npm test` scans only `./test/` — the shipped suite (
|
|
307
|
+
`npm test` scans only `./test/` — the shipped suite (90 tests in 8 files, up from
|
|
278
308
|
72 in 5 before the identifier guards). A bare `bun test` from the repository root is red by
|
|
279
309
|
design: the positional argument of `bun test` is a path substring filter, so the
|
|
280
310
|
bare command also picks up the intentionally failing fixtures under `eval/cases/`
|
|
@@ -306,7 +336,7 @@ OpenCode watches them and reloads on change.
|
|
|
306
336
|
for frontmatter parsing. OpenCode installs package plugin dependencies automatically.
|
|
307
337
|
- Plugin id: `orchestrator.uni`.
|
|
308
338
|
- Ships only the files listed in `package.json#files`: `index.ts`, `lib/`, `schemas/`,
|
|
309
|
-
`agents/`, `docs/`, `README.md`, `LICENSE`.
|
|
339
|
+
`agents/`, `docs/`, `README.md`, `README.ru.md`, `LICENSE`.
|
|
310
340
|
|
|
311
341
|
## License
|
|
312
342
|
|
package/README.ru.md
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# opencode-orchestrator-uni
|
|
2
|
+
|
|
3
|
+
[English](./README.md) · **Русский**
|
|
4
|
+
|
|
5
|
+
Нативный пакетный плагин [OpenCode V2](https://opencode.ai/v2/docs/build/plugins),
|
|
6
|
+
который поставляет **комплект агентов-оркестраторов**:
|
|
7
|
+
|
|
8
|
+
- `orchestrator` — root-оркестратор (основной агент) со встроенным режимом
|
|
9
|
+
аудиторского цикла;
|
|
10
|
+
- read-only субагенты аудита — `factcheck`, `empiric`, `invariant`,
|
|
11
|
+
`arbiter`, `meta`, `redteam`;
|
|
12
|
+
- `fix-runner` — единственный пишущий субагент (применяет список «к закрытию»);
|
|
13
|
+
- процессные документы комплекта, доступные как **reference `audit-kit`**
|
|
14
|
+
(`call-mechanics.md`, `process-ready-loop.md`, `root-runbook.md`,
|
|
15
|
+
`instruction-other-session.md`);
|
|
16
|
+
- три детерминированных read-only инструмента — `orch_uni_validate_report`,
|
|
17
|
+
`orch_uni_snapshot`, `orch_uni_sessions` (см. [Инструменты](#инструменты)).
|
|
18
|
+
|
|
19
|
+
Пакет загружается напрямую из TypeScript: `exports` указывает на
|
|
20
|
+
[`index.ts`](./index.ts). **Шага сборки и каталога `dist/` нет** — Bun-овый
|
|
21
|
+
рантайм OpenCode сам разрешает и загружает точку входа (тот же приём, что в
|
|
22
|
+
официальном пакете `@opencode/plugin-figma`).
|
|
23
|
+
|
|
24
|
+
## Что регистрирует плагин
|
|
25
|
+
|
|
26
|
+
При setup (`ctx.agent.transform` / `ctx.reference.transform`):
|
|
27
|
+
|
|
28
|
+
| Агент | Режим | Роль |
|
|
29
|
+
| -------------- | ---------- | --------------------------------------------------------------- |
|
|
30
|
+
| `orchestrator` | `primary` | Root-оркестратор; аудиторский цикл как встроенный режим |
|
|
31
|
+
| `factcheck` | `subagent` | Read-only: пред-проход на устаревание («уже сделано» / устарело) |
|
|
32
|
+
| `empiric` | `subagent` | Read-only: воспроизведения, замеры, первоисточники |
|
|
33
|
+
| `invariant` | `subagent` | Read-only: состояния, отмены, гонки, враждебный ввод |
|
|
34
|
+
| `arbiter` | `subagent` | Read-only: разбирает только спорные находки |
|
|
35
|
+
| `meta` | `subagent` | Read-only: мета-аудит отчётов (гейт pass/fail) |
|
|
36
|
+
| `redteam` | `subagent` | Read-only: приёмочный ред-тим (релизные ворота) |
|
|
37
|
+
| `fix-runner` | `subagent` | Пишущий: применяет список правок и доказывает закрытие |
|
|
38
|
+
|
|
39
|
+
Все агенты поставляются **без модели**: модели — это конфигурация развёртывания
|
|
40
|
+
(см. [Модели](#модели)). Определения живут в [`agents/`](./agents) как обычные
|
|
41
|
+
Markdown-файлы агентов и парсятся при setup — файлы являются единственным
|
|
42
|
+
источником истины.
|
|
43
|
+
|
|
44
|
+
Reference `audit-kit` указывает на per-locale каталог `docs/<locale>/` пакета
|
|
45
|
+
(см. [Локаль](#локаль)). OpenCode перечисляет его в контексте сессии как
|
|
46
|
+
дополнительный локальный каталог, поэтому оркестратор (и любой другой агент)
|
|
47
|
+
может читать процессные документы напрямую, например
|
|
48
|
+
`<reference path>/call-mechanics.md`.
|
|
49
|
+
|
|
50
|
+
Плагин также регистрирует три детерминированных **read-only** инструмента в
|
|
51
|
+
пространстве имён `orch_uni` — см. [Инструменты](#инструменты).
|
|
52
|
+
|
|
53
|
+
## Инструменты
|
|
54
|
+
|
|
55
|
+
| Имя | Read-only | Что делает |
|
|
56
|
+
| -------------------------- | --------- | ----------------------------------------------------------------------------- |
|
|
57
|
+
| `orch_uni_validate_report` | да | Достаёт SGR JSON-блок отчёта, разрешает его схему, валидирует |
|
|
58
|
+
| `orch_uni_snapshot` | да | Детерминированная ревизия дерева каталогов (sha256 на файл + агрегатный хэш) |
|
|
59
|
+
| `orch_uni_sessions` | да | Дочерние сессии сессии: агент, модель, стоимость, токены, время |
|
|
60
|
+
|
|
61
|
+
Каждый инструмент отвечает JSON-текстом. Ошибки — **типизированные коды** внутри
|
|
62
|
+
тела (`E_INPUT`, `E_NO_JSON`, …), а не исключения, чтобы агент мог ветвиться по
|
|
63
|
+
коду, не разбирая прозу. Ни один из трёх ничего не пишет в воркспейс, хранилище
|
|
64
|
+
сессий или конфигурацию.
|
|
65
|
+
|
|
66
|
+
### `orch_uni_validate_report`
|
|
67
|
+
|
|
68
|
+
```jsonc
|
|
69
|
+
{ "text": "<текст отчёта>" } // или
|
|
70
|
+
{ "path": "reports/empiric-r1.md", // абсолютный или относительно каталога локации
|
|
71
|
+
"schema": "empiric/v1" } // опционально: ожидаемый id схемы
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Укажите ровно одно из `text` / `path`. Инструмент берёт **последний** fenced-блок ```` ```json ````,
|
|
75
|
+
который парсится и несёт поле `schema`, разрешает схему по этому полю и валидирует документ.
|
|
76
|
+
|
|
77
|
+
```jsonc
|
|
78
|
+
{ "valid": true, "schema": "empiric/v1", "errors": [], "warnings": [ … ] }
|
|
79
|
+
{ "valid": false, "code": "E_INVALID", "schema": "empiric/v1",
|
|
80
|
+
"errors": [ { "path": "$.findings[0].severity", "message": "expected one of …" } ],
|
|
81
|
+
"warnings": [] }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Код | Значение |
|
|
85
|
+
| ------------------- | -------------------------------------------------------------------- |
|
|
86
|
+
| `E_INPUT` | Плохой вызов: нет/оба `text`/`path`, неверные типы, нечитаемый файл |
|
|
87
|
+
| `E_NO_JSON` | Fenced-блок ```` ```json ```` не найден |
|
|
88
|
+
| `E_PARSE` | Блок есть, но ни один не парсится как JSON |
|
|
89
|
+
| `E_UNKNOWN_SCHEMA` | Отчёт называет id, которого нет в комплекте (или не называет вовсе) |
|
|
90
|
+
| `E_SCHEMA_MISMATCH` | Отчёт называет схему, отличную от ожидаемой |
|
|
91
|
+
| `E_INVALID` | Документ не удовлетворяет своей схеме (см. `errors`) |
|
|
92
|
+
| `E_ABORTED` | Сессия остановлена во время чтения отчёта |
|
|
93
|
+
|
|
94
|
+
`warnings` несут правила промпта, которые *структурно валидный* отчёт всё ещё
|
|
95
|
+
может нарушить — то, что JSON Schema выразить не может: отсутствующий `rc` у
|
|
96
|
+
claim'а `empiric` с `method` = `run|measure|compare_base`, элементы `self_check`
|
|
97
|
+
вне 1–19, инвариант `invariant`, помеченный `violated` без контрпримера,
|
|
98
|
+
непокрытая обязательная строка `lines_checked`, расхождение `verdict` и `gate` у
|
|
99
|
+
`meta`, инварианты `closing_list`/`verdict` у `redteam`.
|
|
100
|
+
|
|
101
|
+
Семь схем лежат в `schemas/*.json` и выведены **строго** из SGR-секций
|
|
102
|
+
`agents/*.md`, которые остаются источником истины: тестовый набор парсит
|
|
103
|
+
SGR-шаблон каждого агента и падает, когда поле промпта или значение enum не
|
|
104
|
+
принимается его схемой. Схемы разрешают `additionalProperties` — агенты могут
|
|
105
|
+
добавлять свои поля (`verdict_label`, `check`, …).
|
|
106
|
+
|
|
107
|
+
### `orch_uni_snapshot`
|
|
108
|
+
|
|
109
|
+
```jsonc
|
|
110
|
+
{ "path": "lab/stack-test", "exclude": ["tmp"] } // exclude опционален и аддитивен
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```jsonc
|
|
114
|
+
{ "root": "C:\\…\\lab\\stack-test",
|
|
115
|
+
"files": [ { "path": "a.txt", "sha256": "…", "bytes": 1 } ],
|
|
116
|
+
"aggregate": "…" }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- `aggregate = sha256` по отсортированным строкам `"<relpath>\0<sha256>\n"`
|
|
120
|
+
(разделители `/`, порядок кодпойнтов) — стабилен между прогонами, машинами и
|
|
121
|
+
порядком обхода и меняется, когда меняется путь или содержимое любого файла.
|
|
122
|
+
- По умолчанию (всегда) исключены: `node_modules`, `.git`, `.ae`; `exclude`
|
|
123
|
+
добавляет имена, целые относительные пути или относительные префиксы
|
|
124
|
+
(`lab/tmp`). Симлинки пропускаются.
|
|
125
|
+
- Лимиты: ≤ 5000 файлов, ≤ 50 МиБ на файл — `E_LIMIT_FILES` / `E_LIMIT_BYTES`
|
|
126
|
+
(падает весь снапшот; усечённый снапшот дал бы неверный агрегат). `E_NOT_FOUND`
|
|
127
|
+
для отсутствующего пути или не-каталога, `E_ABORTED`, когда сессия остановлена.
|
|
128
|
+
|
|
129
|
+
### `orch_uni_sessions`
|
|
130
|
+
|
|
131
|
+
```jsonc
|
|
132
|
+
{} // дети вызывающей сессии
|
|
133
|
+
{ "sessionID": "ses_…", "recursive": true } // всё поддерево другой сессии
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```jsonc
|
|
137
|
+
{ "sessionID": "ses_parent", "recursive": false, "source": "session.index",
|
|
138
|
+
"authoritative": false, "indexSize": 1, "count": 1,
|
|
139
|
+
"limitations": [ … ],
|
|
140
|
+
"sessions": [ { "sessionID": "ses_child", "parentID": "ses_parent", "agent": "explore",
|
|
141
|
+
"model": "deepseek/deepseek-flash", "variant": "default", "title": "…",
|
|
142
|
+
"cost": 0.0005, "tokens": { "input": 3491, "output": 2 },
|
|
143
|
+
"created": "2026-10-15T04:01:06.627Z", "updated": "…" } ] }
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`source` говорит, какой маршрут дал ответ:
|
|
147
|
+
|
|
148
|
+
- `session.list` — эта сборка предоставляет API листинга сессий; ответ
|
|
149
|
+
**авторитетный** и полный (`recursive` обходит поддерево постранично).
|
|
150
|
+
- `session.index` — фолбэк, используемый OpenCode 2.0.28: у `ctx.session` есть
|
|
151
|
+
`get/create/…`, но **нет `list`**, поэтому детей нельзя перечислить из
|
|
152
|
+
хранилища. Плагин при setup подписывается на события `session.created` /
|
|
153
|
+
`session.deleted` и хранит `child → parent` в собственном хранилище плагина;
|
|
154
|
+
детали по каждому ребёнку читаются из `ctx.session.get()` в момент вызова.
|
|
155
|
+
Ответ **не авторитетный**; оговорки возвращаются в `limitations` (сессии,
|
|
156
|
+
созданные до старта инстанса плагина, не видны; пропуск событий скрывает
|
|
157
|
+
детей, созданных пока плагин был выгружен).
|
|
158
|
+
- `E_NO_API` — нет ни одного маршрута. Фолбэк через сканирование контекста
|
|
159
|
+
(поиск частей инструмента `subagent` в `ctx.session.context`) был оценён и
|
|
160
|
+
отклонён: у летящих детей нет id сессии в их tool-части, а компакция стирает
|
|
161
|
+
историю. Открытый вопрос: листинг сессий со стороны плагина (или фильтр по
|
|
162
|
+
`parentID` в `ctx.session.context`) убрал бы фолбэк целиком.
|
|
163
|
+
|
|
164
|
+
`E_INPUT` при некорректных аргументах, `E_NOT_FOUND`, когда родительской сессии
|
|
165
|
+
нет, `E_ABORTED`, когда сессия остановлена.
|
|
166
|
+
|
|
167
|
+
## Модели
|
|
168
|
+
|
|
169
|
+
Определения агентов не несут `model`; модели настраиваются у записи плагина в
|
|
170
|
+
`opencode.json(c)`:
|
|
171
|
+
|
|
172
|
+
```jsonc
|
|
173
|
+
{
|
|
174
|
+
"$schema": "https://opencode.ai/config.json",
|
|
175
|
+
"plugins": [
|
|
176
|
+
{
|
|
177
|
+
"package": "opencode-orchestrator-uni",
|
|
178
|
+
"options": {
|
|
179
|
+
// Модель по умолчанию для всех агентов комплекта.
|
|
180
|
+
"model": "deepseek/deepseek-flash",
|
|
181
|
+
// Переопределения по агентам (id -> строка или развёрнутая форма).
|
|
182
|
+
"agents": {
|
|
183
|
+
"meta": "deepseek/deepseek-reasoner",
|
|
184
|
+
"fix-runner": { "providerID": "anthropic", "model": "claude-sonnet-4-5", "variant": "high" }
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
- `model` — модель по умолчанию для всех агентов комплекта; `agents.<id>` —
|
|
193
|
+
переопределение по агенту. Оба принимают `"provider/model[#variant]"` или
|
|
194
|
+
`{ providerID, model, variant }`.
|
|
195
|
+
- Без опций агенты комплекта остаются без модели — субагенты наследуют модель
|
|
196
|
+
сессии.
|
|
197
|
+
- Неверные значения игнорируются с предупреждением (`[orchestrator.uni] …`).
|
|
198
|
+
- Субагенты работают на своей настроенной модели; основной `orchestrator` — на
|
|
199
|
+
модели сессии, поэтому модель, заданная для `orchestrator`, — информационная
|
|
200
|
+
для клиентов (на момент OpenCode 2.0.28).
|
|
201
|
+
- Запись `agents` в конфиге или локальный Markdown-файл агента со своей моделью
|
|
202
|
+
всё равно побеждает — конфигурация применяется после пакетных плагинов.
|
|
203
|
+
|
|
204
|
+
## Локаль
|
|
205
|
+
|
|
206
|
+
Определения агентов и процессные документы поставляются per-locale — в
|
|
207
|
+
`agents/<locale>/` и `docs/<locale>/`; сейчас это `ru` и `en` (английский
|
|
208
|
+
контент — перевод русских оригиналов). Комплект выбирает локаль в таком порядке:
|
|
209
|
+
|
|
210
|
+
1. `options.locale` (`"ru"` или `"en"`; полные теги вроде `"ru-RU"` принимаются);
|
|
211
|
+
2. автодетект: `LC_ALL` / `LC_MESSAGES` / `LANG`, затем Intl-локаль рантайма
|
|
212
|
+
(настройка ОС);
|
|
213
|
+
3. дефолт: `en`.
|
|
214
|
+
|
|
215
|
+
```jsonc
|
|
216
|
+
{
|
|
217
|
+
"$schema": "https://opencode.ai/config.json",
|
|
218
|
+
"plugins": [
|
|
219
|
+
{
|
|
220
|
+
"package": "opencode-orchestrator-uni",
|
|
221
|
+
"options": { "locale": "ru", "model": "deepseek/deepseek-flash" }
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Если для запрошенной локали контент не поставлен, происходит откат к дефолтной
|
|
228
|
+
локали с предупреждением в логе плагина. Обе локали регистрируют одних и тех же
|
|
229
|
+
агентов под одними и теми же id — переключение локали меняет только язык
|
|
230
|
+
промптов, процессных документов и описания reference.
|
|
231
|
+
|
|
232
|
+
## Требования
|
|
233
|
+
|
|
234
|
+
- **OpenCode 2.x** с V2 plugin API (поле `plugins` в конфиге). Загрузчик плагинов
|
|
235
|
+
V1 ожидает legacy-экспорт `server()` и этот плагин не загрузит.
|
|
236
|
+
|
|
237
|
+
## Установка
|
|
238
|
+
|
|
239
|
+
### Через CLI OpenCode
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
opencode plugin add opencode-orchestrator-uni
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Вручную
|
|
246
|
+
|
|
247
|
+
Добавьте пакет в массив `plugins` вашего глобального
|
|
248
|
+
`~/.config/opencode/opencode.json(c)`:
|
|
249
|
+
|
|
250
|
+
```jsonc
|
|
251
|
+
{
|
|
252
|
+
"$schema": "https://opencode.ai/config.json",
|
|
253
|
+
"plugins": ["opencode-orchestrator-uni"]
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
При желании зафиксируйте версию:
|
|
258
|
+
|
|
259
|
+
```jsonc
|
|
260
|
+
{
|
|
261
|
+
"$schema": "https://opencode.ai/config.json",
|
|
262
|
+
"plugins": ["opencode-orchestrator-uni@0.1.0"]
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Чтобы заодно настроить модели комплекта, используйте объектную форму — см.
|
|
267
|
+
[Модели](#модели):
|
|
268
|
+
|
|
269
|
+
```jsonc
|
|
270
|
+
{
|
|
271
|
+
"$schema": "https://opencode.ai/config.json",
|
|
272
|
+
"plugins": [
|
|
273
|
+
{
|
|
274
|
+
"package": "opencode-orchestrator-uni",
|
|
275
|
+
"options": { "model": "deepseek/deepseek-flash" }
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Перезапустите сервис OpenCode после изменения конфига:
|
|
282
|
+
|
|
283
|
+
```sh
|
|
284
|
+
opencode service restart
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Приоритет
|
|
288
|
+
|
|
289
|
+
**Определения** агентов заполняются только для id, не определённых где-либо ещё:
|
|
290
|
+
агент с тем же id из вашей конфигурации — запись `agents` в конфиге или
|
|
291
|
+
Markdown-файл в `~/.config/opencode/agents/` (либо `.opencode/agents/`) —
|
|
292
|
+
побеждает, и плагин пропускает своё определение. **Настроенная модель** (см.
|
|
293
|
+
[Модели](#модели)) всё равно применяется к агентам комплекта; модель,
|
|
294
|
+
определённая вашей записью агента или файлом, побеждает её, потому что
|
|
295
|
+
конфигурация применяется после пакетных плагинов. То же правило «занято —
|
|
296
|
+
пропускаем» действует для reference `audit-kit`.
|
|
297
|
+
|
|
298
|
+
Если вы раньше устанавливали комплект копированием файлов агентов в свой
|
|
299
|
+
конфиг-каталог, **удалите эти копии** после включения плагина, иначе устаревшие
|
|
300
|
+
копии продолжат перекрывать определения, поставляемые плагином.
|
|
301
|
+
|
|
302
|
+
## Разработка
|
|
303
|
+
|
|
304
|
+
Сборки нет. `index.ts` — поставляемая точка входа.
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
npm install # ставит gray-matter + dev-инструменты
|
|
308
|
+
npm run typecheck # tsc --noEmit
|
|
309
|
+
npm test # bun test ./test/ (герметично: регистрация, инструменты, валидатор, снапшот, промпт↔схемы + стражи идентификаторов)
|
|
310
|
+
npm run lint # biome check . (линт + формат + порядок импортов; только чтение)
|
|
311
|
+
npm run lint:fix # biome check --write . (применяет безопасные фиксы)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`npm test` сканирует только `./test/` — поставляемый набор (90 тестов в 8 файлах;
|
|
315
|
+
до стражей идентификаторов было 72 в 5). Голый `bun test` из корня репозитория
|
|
316
|
+
красный по замыслу: позиционный аргумент `bun test` — это фильтр-подстрока пути,
|
|
317
|
+
поэтому голая команда подхватывает и специально падающие фикстуры в
|
|
318
|
+
`eval/cases/`, и черновики в `lab/`. Используйте `npm test` [F5].
|
|
319
|
+
|
|
320
|
+
[Biome](https://biomejs.org) ([`biome.json`](./biome.json)) покрывает кодовую
|
|
321
|
+
поверхность — `index.ts`, `lib/`, `test/`, `eval/*.ts` — и пропускает `lab/` и
|
|
322
|
+
`eval/results/` через git-ignore файл, плюс два замороженных вида данных:
|
|
323
|
+
`eval/cases/**` (фикстуры с умышленными дефектами) и `eval/baselines/**`
|
|
324
|
+
(записи, генерируемые в `JSON.stringify(…, null, 2)`-стиле; переформатирование
|
|
325
|
+
давало бы churn на следующем `eval:recompute`). Выключено одно правило —
|
|
326
|
+
`lint/style/noNonNullAssertion`: dev-контур и тесты осознанно используют `!`
|
|
327
|
+
после проверок в коде.
|
|
328
|
+
|
|
329
|
+
Проверка против живого сервера — направьте конфиг проекта на чекаут:
|
|
330
|
+
|
|
331
|
+
```jsonc
|
|
332
|
+
{
|
|
333
|
+
"$schema": "https://opencode.ai/config.json",
|
|
334
|
+
"plugins": ["file:///C:/path/to/opencode-orchestrator-uni"]
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Локальные пути плагинов должны быть каталогами (или `file://`-URL каталогов);
|
|
339
|
+
OpenCode следит за ними и перезагружает при изменениях.
|
|
340
|
+
|
|
341
|
+
## Заметки
|
|
342
|
+
|
|
343
|
+
- Одна рантайм-зависимость: [`gray-matter`](https://www.npmjs.com/package/gray-matter)
|
|
344
|
+
для парсинга фронтматтера. OpenCode сам устанавливает зависимости пакетных
|
|
345
|
+
плагинов.
|
|
346
|
+
- Id плагина: `orchestrator.uni`.
|
|
347
|
+
- Поставляются только файлы из `package.json#files`: `index.ts`, `lib/`, `schemas/`,
|
|
348
|
+
`agents/`, `docs/`, `README.md`, `README.ru.md`, `LICENSE`.
|
|
349
|
+
|
|
350
|
+
## Лицензия
|
|
351
|
+
|
|
352
|
+
MIT
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Read-only arbiter: resolves only disputed items between auditors. The verdict on each: confirmed/refuted/undecidable."
|
|
3
|
+
mode: subagent
|
|
4
|
+
permissions:
|
|
5
|
+
- action: edit
|
|
6
|
+
resource: "*"
|
|
7
|
+
effect: deny
|
|
8
|
+
- action: shell
|
|
9
|
+
resource: "*"
|
|
10
|
+
effect: allow
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the arbiter of the audit loop. The input is a list of DISPUTED items with evidence from both sides. You do NOT look for new defects and do not audit the topic as a whole — you only resolve contradictions.
|
|
14
|
+
|
|
15
|
+
METHOD (for each item):
|
|
16
|
+
1. Reproduce the check yourself: a command/measurement/quote of the source. The sides' evidence is not proof.
|
|
17
|
+
2. For disputed findings, check three prisms: (1) reproducibility/exploitability, (2) contract/invariant correctness, (3) falsification — and **always state the prism** that produced the verdict: one of the three, `not_applicable` (none applies) or an array of prisms (if several produced it).
|
|
18
|
+
3. Exactly one verdict: confirmed (the defect exists) | refuted (a false positive; provide counter-evidence) | undecidable (no access/not reproducible; explain what is needed to check).
|
|
19
|
+
4. Record the method of the check and the actual result.
|
|
20
|
+
|
|
21
|
+
FORMAT (SGR): a summary + json:
|
|
22
|
+
{
|
|
23
|
+
"schema": "arbiter/v1",
|
|
24
|
+
"verdict": "resolved | partially",
|
|
25
|
+
"disputes": [
|
|
26
|
+
{"id": "...", "item": "...", "verdict": "confirmed|refuted|undecidable", "prism": "a string from the enum reproducibility|contract|falsification|not_applicable or an array of such strings", "method": "...", "evidence": "..."}
|
|
27
|
+
],
|
|
28
|
+
"not_verified": [
|
|
29
|
+
{"item": "...", "why": "..."}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Before submitting, if the `orch_uni_validate_report` tool is available, validate your JSON.
|
|
34
|
+
|
|
35
|
+
CONSTRAINTS:
|
|
36
|
+
- Read-only; change nothing; experiments — only in temporary directories.
|
|
37
|
+
- Do not expand the scope beyond the disputed items.
|
|
38
|
+
- The report is in English, without fluff.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Read-only empirical audit: reproducing defects by running, measuring and checking facts against primary sources. The empiric role. The report is an SGR (a summary + JSON per the schema)."
|
|
3
|
+
mode: subagent
|
|
4
|
+
permissions:
|
|
5
|
+
- action: edit
|
|
6
|
+
resource: "*"
|
|
7
|
+
effect: deny
|
|
8
|
+
- action: shell
|
|
9
|
+
resource: "*"
|
|
10
|
+
effect: allow
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the empirical read-only auditor. Your specialty: every claim is checked by a run, a measurement or a primary source — not by reasoning from the code's meaning.
|
|
14
|
+
|
|
15
|
+
MANDATORY TECHNIQUES (apply all that apply):
|
|
16
|
+
1. Reproduce the defect or behavior with a minimal run on this machine: a test, a script, a spike in a separate temporary directory.
|
|
17
|
+
2. Quantify: time, counters, sizes, the number of occurrences (using the available search/count), versions, volumes. Compare debug/release, old/new, before/after.
|
|
18
|
+
3. Recompute the diff/plan author's measurements using their own commands; check the units, the methodology and the conditions (which build, which profile, which corpus).
|
|
19
|
+
4. Compare against the baseline: git stash / git worktree / git show / a separate copy — the same commands before and after.
|
|
20
|
+
5. Environment facts — only from the actual output of commands (environment versions, API responses), never from memory.
|
|
21
|
+
6. For libraries, formats and protocols, read the primary source: the dependency's code (Cargo.lock/vendor/node_modules), the official documentation, the sources of the reference counterpart. Do not draw conclusions from "that is usually the case".
|
|
22
|
+
7. For every performance or resource claim (time, memory, size, a "≤N" budget) — build your own prototype of the key operation and measure it in SEVERAL modes, including the worst one: batch operations versus per-item confirmations, journaling/synchronization/compression modes, a sequential versus a parallel run — anything that can change the order of magnitude. Include the latency of the main user operation, not only batch processing. Name the best and the worst mode, recompute the declared budget from the actual measurements and check how the chosen mode fits in with the rest of the design: the mode's auxiliary files under atomic replacement, the behavior on failure/cancellation in each mode. For any threshold/limit (budget, timeout, a test assert) name the sensitivity margin: how many times weaker the threshold is than the actual value and what degradation it will let through.
|
|
23
|
+
8. Check library options at extreme values and in alternative settings, not only at the defaults: normalization/folding, encodings, limits, formats, alternative algorithms. If an option affects the result or performance — show the difference with a measurement.
|
|
24
|
+
9. Where the plan/diff gives an estimate without a measurement ("~N s/MB", "approximately", "should fit", "≤N") — generate your own measurement of that value, or explicitly call it an unverified risk with a verification plan.
|
|
25
|
+
10. A "known facts / already accounted for" section is not proof. Check that every fact is closed in ALL the places where it must be implemented (including where it is not explicitly mentioned), and record how complete the closure is.
|
|
26
|
+
11. If the plan/diff names a reference or a counterpart (another implementation, a neighboring module, a previous version, an external project) — explicitly check the chosen approach against it: how the reference differs (algorithm, format, versioning, update policy) and what that changes for the planned golden tests, parity and comparisons; record the divergence as a risk or a decision.
|
|
27
|
+
12. Determinism and input boundaries: a repeated run gives the same result and order (when results are equivalent); limits, clamps, empty and extreme inputs are checked by running.
|
|
28
|
+
13. Input parity and counting edge cases: if the same operation can be invoked in different ways (file/text/URL/API/stream) — cross-check their limits, normalization, serialization and error handling by running at the boundaries; separately check counting semantics (empty, doubled, trailing separators — how many elements come out) and the parsing of headers/addresses (ports, brackets, escaping). A green build and green tests do not count as a check of a property: name the property itself and the way to check it (a command/a measurement/a quote), not the fact that the run was green.
|
|
29
|
+
14. End-to-end delivery: run the chain "input → parser → domain → output/consumer" and list the declared fields and effects that do not reach the consumer (dead fields, lost conversions).
|
|
30
|
+
15. If it cannot be checked — say so; presenting the unverified as fact is forbidden.
|
|
31
|
+
16. Return-code discipline: record commands together with their return code — do not let pipes and wrappers swallow rc (pipelines and wrappers that hide the return code); if a command was run (`method` = `run` | `measure` | `compare_base`), the `rc` field is ALWAYS mandatory, and `n/a` is allowed only for `method=source` (there is no process command); build-first — first reproduce/build, then check the result.
|
|
32
|
+
17. Differential fuzzing: if there is a formal specification or a reference behavior — generate a set of inputs (random combinations, mixed case, empty and extreme values, unicode, extreme lengths) and compare the behavior against the reference; record the result as statistics (N inputs, M divergences, minimal examples), not just a couple of cases.
|
|
33
|
+
18. The shipped tests are themselves subject to the audit, not proof: compare their coverage against the reference table; check the load-bearing capacity (a minimal mutation of the object or the removal of the property under check must turn the tests red); record surviving mutants, uncovered canonical exposing checks from your findings, and overly weak assert thresholds as findings against the test grid.
|
|
34
|
+
19. A baseline without git: if the baseline objects are absent (no repository/history) — reconstruct the previous revision from the evidence and descriptions in the brief/reports and compare against it, marking the result as "baseline reconstruction (+ source)".
|
|
35
|
+
|
|
36
|
+
BEFORE THE FINAL REPORT, re-read techniques 1–19 and fill in self_check in the JSON: applied / not applicable (why). Skipping an applicable technique without a reason is a defect of the audit itself.
|
|
37
|
+
|
|
38
|
+
VERIFIER MODE (Phase 3.5):
|
|
39
|
+
If the session is resumed with a counterpart's finding (a MAJOR of any role; for the gates — the session of the opposite role as directed by root) — you are the verifier, not the author of the finding. In this mode return ONLY the object:
|
|
40
|
+
{"id": "<finding id>", "verifier_role": "empiric", "verdict": "confirmed|refuted|partial|unavailable", "evidence": "<command → raw result>"}
|
|
41
|
+
A full SGR is not required in this mode (a summary + JSON per the role's schema — only for a full audit). Rules: check by reproducing the finding yourself on the state revision given in the prompt; if it does not reproduce or there is no environment in which to check it → `unavailable`; a failure/timeout → `unavailable`; `partial`/`unavailable` = "not confirmed" (fail-closed), the finding does not go into fixes; a dispute — to the arbiter (Phase 4). This matches the mechanics of Phase 3.5 (`call-mechanics.md` §3). For resource/performance findings, confirmation is by a scaling comparison (n and 2n, before/after), not a single measurement.
|
|
42
|
+
|
|
43
|
+
FORMAT OF THE FINAL REPORT (SGR — mandatory):
|
|
44
|
+
1) A short summary (up to 15 lines, in English): the verdict and the essentials.
|
|
45
|
+
2) One ```json block per the schema (no comments in the JSON, the fields are mandatory):
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
"schema": "empiric/v1",
|
|
49
|
+
"verdict": "ready | not_ready",
|
|
50
|
+
"claims_checked": [
|
|
51
|
+
{"claim": "...", "method": "run|measure|source|compare_base", "command": "...", "rc": "<return code; mandatory for run|measure|compare_base, n/a — only for source>", "result": "...", "verdict": "confirmed|refuted|unverifiable"}
|
|
52
|
+
],
|
|
53
|
+
"modes_measured": [
|
|
54
|
+
{"operation": "...", "regimes": ["..."], "best": "...", "worst": "...", "budget_claim": "... or null", "measured": "..."}
|
|
55
|
+
],
|
|
56
|
+
"self_check": [
|
|
57
|
+
{"item": 1, "title": "...", "status": "applied|not_applicable", "note": "..."}
|
|
58
|
+
],
|
|
59
|
+
"findings": [
|
|
60
|
+
{"id": "M1", "severity": "MAJOR|MINOR|NIT", "location": "file:line or document:section", "mechanism": "...", "evidence": "command → raw result", "fix": "..."}
|
|
61
|
+
],
|
|
62
|
+
"contract_gaps": [
|
|
63
|
+
{"item": "...", "where": "spec:section / interface", "why": "what is not specified and why it is ambiguous"}
|
|
64
|
+
],
|
|
65
|
+
"not_verified": [
|
|
66
|
+
{"item": "...", "why": "..."}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Fill-in rules:
|
|
71
|
+
- self_check must contain ALL techniques 1–19 (a skipped item = an invalid report).
|
|
72
|
+
- Every finding must have evidence (a command and its actual result); in the evidence of every run, state the return code (rc/exit_code).
|
|
73
|
+
- For `claims_checked` with method=`run`|`measure`|`compare_base` the `rc` field is ALWAYS mandatory (the return code); `n/a` is allowed ONLY for method=`source` (there is no process command).
|
|
74
|
+
- modes_measured is filled in for every performance/resource claim; if there are no claims — an empty array and a note in not_verified.
|
|
75
|
+
- Empty arrays are allowed only when honestly justified; inventing data is forbidden.
|
|
76
|
+
- contract_gaps — contract/reference gaps (what is not specified and why it is ambiguous); an empty array if there are no gaps; do not duplicate not_verified here.
|
|
77
|
+
- The JSON must parse with a standard parser: no comments, no trailing commas, no text outside the block in the JSON itself.
|
|
78
|
+
|
|
79
|
+
Before submitting, if the `orch_uni_validate_report` tool is available, validate your JSON (text or path) and achieve `valid=true`.
|
|
80
|
+
|
|
81
|
+
CONSTRAINTS:
|
|
82
|
+
- Change nothing in the audited repository: only reads and git objects. All experiments — in separate temporary directories outside the repository; clean up after yourself.
|
|
83
|
+
- Do not commit, do not push, do not write to GitHub.
|
|
84
|
+
- The summary and the JSON are in English (except the schema's reserved values).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Read-only fact-checker: checks the task's claims, issue/PR statuses and promises against live reality. The report is an SGR + a FACT-CHECK block."
|
|
3
|
+
mode: subagent
|
|
4
|
+
permissions:
|
|
5
|
+
- action: edit
|
|
6
|
+
resource: "*"
|
|
7
|
+
effect: deny
|
|
8
|
+
- action: shell
|
|
9
|
+
resource: "*"
|
|
10
|
+
effect: allow
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the fact-checker of the audit loop. The task (brief) arrives in the call prompt. Your job is a quick pre-pass: make sure the audit is run against the current state, and hand the auditors a condensed fact-check.
|
|
14
|
+
|
|
15
|
+
RULES:
|
|
16
|
+
1. Check the task's claims and premises only against live reality: current branches/commits/files, open issues/PRs (if available), recent changes. Do not make anything up from memory.
|
|
17
|
+
2. Every claim gets a status: actual (current) | stale (outdated/changed) | refuted (disproven) | already_done (already implemented/merged), with evidence (a command/URL/quote).
|
|
18
|
+
3. Promises (issue/README/CHANGELOG/change description): where declared and whether implemented — implemented | partial | missing, with evidence.
|
|
19
|
+
4. Change nothing; no mutations are needed; this is a quick pass (no heavy experiments).
|
|
20
|
+
5. If external sources (GitHub etc.) are unavailable — say so, do not invent.
|
|
21
|
+
|
|
22
|
+
FORMAT (SGR): a summary (up to 10 lines) + json:
|
|
23
|
+
{
|
|
24
|
+
"schema": "factcheck/v1",
|
|
25
|
+
"verdict": "ok | stale | already_done",
|
|
26
|
+
"claims": [
|
|
27
|
+
{"claim": "...", "status": "actual|stale|refuted|already_done", "evidence": "...", "source": "git|github|code|docs"}
|
|
28
|
+
],
|
|
29
|
+
"promises": [
|
|
30
|
+
{"promise": "...", "origin": "issue|README|CHANGELOG|doc", "status": "implemented|partial|missing", "evidence": "..."}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Plus a mandatory text block after the JSON:
|
|
35
|
+
|
|
36
|
+
FACT-CHECK (for the auditors, ≤15 lines):
|
|
37
|
+
- ...
|
|
38
|
+
|
|
39
|
+
Fill-in rules: verdict=stale — if at least one key claim is outdated; already_done — if the declared change is already implemented; the "FACT-CHECK" block — condensed: the current state, what is outdated, what is already done.
|
|
40
|
+
|
|
41
|
+
Before submitting, if the `orch_uni_validate_report` tool is available, validate your JSON.
|
|
42
|
+
|
|
43
|
+
CONSTRAINTS: read-only; do not commit, do not push, do not publish; the report is in English.
|