/dr-orchestrate
Самоуправляемый Datarim pipeline на базе tmux — Phase 2 (Subagent Inference, автономность L2)
Обзор
/dr-orchestrate — референсный non-core плагин фреймворка. Phase 1 (v2.3.0) — lean rule-based tmux runner. Phase 2 (v2.4.0) добавляет subagent inference, который активируется когда rule-based парсер не может классифицировать строку pane, плюс flock-race-safe cooldown и audit schema v2. Автономность плагина теперь L2 (assisted): эскалацию по-прежнему контролирует человек, но unknown prompts больше не упираются в парсер.
Плагин лежит в plugins/dr-orchestrate/ в репозитории фреймворка и включается стандартным CLI (/dr-plugin).
Использование
# Однократно включить плагин
/dr-plugin enable dr-orchestrate
# Опционально: разрешить send-keys (по умолчанию fail-closed)
cp ~/.claude/plugins/dr-orchestrate/user-config.template.yaml \
~/.claude/plugins/dr-orchestrate/user-config.yaml
chmod 600 ~/.claude/plugins/dr-orchestrate/user-config.yaml
$EDITOR ~/.claude/plugins/dr-orchestrate/user-config.yaml # key_injection: true
# Один цикл Phase 2 (parse → resolver → autonomous-or-escalate)
/dr-orchestrate run
# Сухой прогон для валидации
/dr-orchestrate run --dry-run
# Вручную классифицировать вставленный prompt без consume tmux pane
/dr-orchestrate run --unknown-prompt "operator paste: > /dr-prd ready for strategy gate"
Subagent Inference (Phase 2)
На miss парсера (confidence: 0) cmd_run.sh передаёт управление в subagent_resolver.sh, который классифицирует текст pane через настраиваемый fallback-chain AI CLI бэкендов:
- coworker-deepseek (default primary) —
coworker ask --provider deepseek --profile code; vendor-neutral OSS CLI. - claude —
claude --print --output-format=json; wrapper приходит как{type, result}, resolver повторно парсит.result. - codex —
codex exec --output-last-message -; best-effort, chain продолжается при parse fail.
Каждый бэкенд имеет 15 с wall-clock budget (DR_ORCH_RESOLVER_TIMEOUT_S), запускается с закрытым FD 3 (bats-harness compatibility), молча пропускается при отсутствии бинаря в $PATH (one-time WARN при первом промахе, дедуп через $STATE_DIR/.warned.<backend>). Lenient JSON extractor обрабатывает raw тело, fenced ```json блоки, и prose-wrapped объекты.
Решение autonomous-vs-escalate живёт в cmd_run.sh, gated на subagent.confidence_threshold (default 0.80). Выход resolver ниже порога (или chain_exhausted) маршрутизируется в escalation sink; на/выше порога — проходит через decision-cooldown gate перед любым autonomous-действием.
Escalation
Два бэкенда подключены в Phase 2 (переопределяется через DR_ORCH_ESCALATION_BACKEND):
- mock (default) — добавляет JSONL событие в
~/.local/share/dr-orchestrate/escalation.jsonlс frozen-схемой (schema_version,cycle_id,pane_id,prompt_hash,action_suggested,confidence,reason,subagent_model,backend_used,escalation_backend,mock). - dev-bot — stub, возвращает exit 99 с WARN до появления реального consumer-сервиса.
Security floor
Каждый tmux send-keys и каждое autonomous-решение проходят фиксированный fail-closed pipeline:
- Whitelist — разрешены только
[a-zA-Z0-9 _-./:=@]. Всё остальное → блок + audit. - Escape-block — любой байт
0x1bотвергается. - Micro-cooldown — 500 мс gate на каждый send в pane.
- Decision-cooldown — 60 с gate на каждое autonomous-решение в pane (теперь достигается через resolver path).
- Flock-safe lock (Phase 2) —
flock -nper (pane, kind) на Linux; macOS hosts выдают one-time WARN и работают на non-atomic semantics Phase 1. - Violation tracker — 5 нарушений любого типа за час → pane заблокирован на 1 час.
Audit (schema v2)
Phase 2 вводит make_event_v2 рядом с Phase 1 emitter. Schema v2 расширяет v1 6-field event метаданными resolver/escalation:
{
"schema_version": 2,
"timestamp": "2026-05-11T08:00:00Z",
"matched_text_hash": "af86d…",
"command": "/dr-do",
"exit_code": 0,
"duration_ms": 1421,
"pane_id": "datarim:0.0",
"confidence": 0.87,
"subagent_model": "deepseek-chat",
"backend_used": "coworker-deepseek",
"escalation_backend": "",
"stage": "resolve",
"outcome": "resolved",
"reason": "explicit slash-command"
}
Hash-only-credentials инвариант сохраняется — сырой текст pane никогда не попадает в лог. Поле reason усечено до 500 символов и grep-redacted для паттернов password=, token=, secret=, credential=, api_key= перед записью.
Конфигурация
# user-config.yaml
subagent:
fallback_chain: ["coworker-deepseek", "claude", "codex"]
timeout_s: 15
confidence_threshold: 0.80
escalation:
backend: "mock"
mock_log: ~/.local/share/dr-orchestrate/escalation.jsonl
Уровни автономности
- Phase 1 — L1 (manual; rule-based confidence; без обучения).
- Phase 2 — L2 (assisted; multi-backend subagent inference + race-safe cooldown + audit v2).
- Phase 3 — L4 (план: самообучающиеся правила с 24-часовой re-валидацией).
Soak verdict
В составе плагина — dev-tools/measure-orchestrator-soak.sh, verdict-gate вычисляющий false_escalate_rate = escalated / (resolved + escalated) по событиям audit schema v2. Default порог < 0.15 за последние 48 ч.
Bot-Interaction Interface (v2.5.0+)
С Datarim v2.5.0 / plugin v0.3.0 у оркестратора появляется программный IO surface в дополнение к tmux pane — framework-owned wire contract, через который бот (или любой HTTP-клиент) может отправлять промпты и получать события эскалации/прогресса.
- OpenAPI 3.1 spec —
plugins/dr-orchestrate/openapi/orchestrator-interface.yaml. Один входящий эндпойнтPOST /orchestrator/input, Bearer-авторизация, JSON-тело (session_id,command,ts, опциональноmeta). Default-ответ —202 Accepted; sync-shortcut (200 + inline body) только для whitelist-команд (dr-status,dr-help) при заголовкеX-Sync-Timeout(hard-cap ≤ 2000 мс). - Reference impl —
adnanh/webhookv2.8.3 (Go single binary, MIT, без runtime-зависимостей) +config/hooks.yaml+scripts/orchestrator-input-handler.sh. Адаптер валидирует Bearer против Vault-секрета, проверяет JSON-schema и атомарно пишет ULID-named файл в~/.local/share/datarim-orchestrate/inbox/. Главный цикл (cmd_run.sh) per cycle забирает oldest-first из inbox и инжектит.commandкакUNKNOWN_TEXTв существующий semantic-parser → resolver pipeline. - Outbound emitter —
_emit_devbotвescalation_backend.shзаменяет v0.2.x stub. Два бэкенда (переключаются черезDR_ORCH_OUTBOUND_BACKEND):callback(default — HMAC-SHA256 +X-Timestamp300 с replay-window, curl POST наDR_ORCH_ESCALATION_DEVBOT_URL) иredis(opt-in —redis-cli PUBLISH orchestrator-out:{session_id}черезDR_ORCH_OUTBOUND_REDIS_URL). - Activation gate — при unset
DR_ORCH_ESCALATION_DEVBOT_URL_emit_devbotмолчаreturn 0(noop). Rollback =unsetпеременной. Откат кода не требуется. - Network exposure — Tier 1. Reference impl слушает
127.0.0.1:8090(loopback, single-tenant). Redis-бэкенд использует существующий Tailscale-only listener (без нового Tier 3 surface). - Contract-тесты —
tests/contract/run-schemathesis.sh+ CI workflow.github/workflows/dr-orchestrate-contract.ymlподнимают reference impl на ephemeral-порту и гоняют schemathesis property-based fuzz против OpenAPI-спеки.dev-tools/check-agent0017-live.sh— ручной pre-activation gate (curl /healthz+ smokePOST /prompts) перед выставлением production env.
Не входит в Phase 2
UI Telegram-моста, write-путь самообучающихся правил (Phase 3), реальный dev-bot HTTP endpoint, переписывание Vault secrets_backend.sh, embedding/vector классификация, multi-host SSH aggregation, Docker/Kubernetes orchestration, нативный Windows.