@piligrimnick/claude-codex-hybrid-tdd-dev
v0.1.0
Published
Hybrid Claude+Codex TDD workflow for autosk: spec -> architect -> tester -> test-review (pair) -> dev -> review (pair) -> security -> finalizer -> accept -> cleanup.
Downloads
20
Maintainers
Readme
autosk-hybrid-dev
Гибридный Claude+Codex TDD-конвейер для autosk по дизайну
~/sites/docs/specs/2026-07-18-agent-pipeline-design.md (профиль C).
Граф
spec → architect → tester → test-review → dev → review → security → finalizer → accept (human) → cleanup → done
│ ▲ │ ▲ │ │
└→ spec └─────────┘ (block) └──────┘ (bounce) └→ dev (bounce)
accept → pr → accept # ручной PR: autosk resume <id> --to pr
human → dev-manual → review # ручной обход dev-капа: autosk resume <id> --to dev-manualРоли и модели (гибридный профиль)
| Шаг | Воркер(ы) | Модель / effort | Ограничения роли | |---|---|---|---| | spec | claude | opus:high | только спека; декомпозиция запрещена | | architect | codex | gpt-5.6-sol:high | контракты + план; спеку не меняет | | tester | claude | sonnet:high → opus:high на последней попытке | только тесты | | test-review | codex + claude | sol:high + opus:high, read-only, AND-вердикт | JSON-отчёты, синтез в TS | | dev | codex | по complexity-метке: simple=luna:high, standard=terra:medium, complex=sol:medium → sol:high на последней попытке | только код, тесты не трогает | | review | claude + codex | opus:high + sol:high, read-only, AND-вердикт | blocking только с file/line/fix | | security | claude | opus:high | одиночный (sol на security проблемна) | | finalizer | claude | haiku:low | чек-лист, ничего не меняет | | pr | claude | sonnet:medium | ручной, merge не делает |
Маршрутизация dev по сложности
Архитектор (он уже изучил и задачу, и код) ставит в своём комментарии метку
complexity: simple|standard|complex; dev-обёртка читает последнюю метку из ленты
и выбирает модель:
simple→ luna:high — контекст-лёгкая механика (переименования, spacing, крошечный UI), где дешёвая luna оправдана;standard→ terra:medium — обычный багфикс / чётко очерченная фича (default);complex→ sol:medium — auth, платежи, миграции, архитектура, сложные баги;- провал петли dev↔review → sol:high; sol:xhigh — только ручной
dev-manual.
Почему standard = terra:medium, а не luna:xhigh (ресёрч, 2026-07, см. дизайн-док): terra обгоняет luna на всех четырёх кодинг-бенчмарках даже при равном reasoning effort; luna:xhigh по стоимости ≈ terra:medium (дешёвый токен luna съедается xhigh-ризонингом); у luna обваливается long-context recall (~41% MRCR против ~90% у terra) — прямой риск для агентного цикла в реальном репо. simple остаётся на luna именно потому, что такие задачи контекст-лёгкие и слабость luna там не срабатывает.
Лимиты (onTransit)
dev: 4 автоматических входа (последний — эскалация на sol), дальшеhuman; обход —dev-manual.tester: 5 входов (последний — эскалация на opus).spec: 2 возврата.prтолько изacceptи обязан вернуться вaccept;cleanupтолько изaccept.
Динамическое управление капами (без рестарта)
Капы читаются из живого состояния задачи, поэтому подстраиваются на лету двумя способами:
- Сброс счётчика (кап снова начнёт считать с нуля):
autosk metadata set <id> step_visits.dev 0 # обнулить счётчик dev autosk metadata unset <id> step_visits # обнулить все - Отключить/подстроить сам кап на конкретной задаче (через
metadata.cap_overrides, читается вonTransit):
Значения:autosk metadata set <id> cap_overrides.dev false # снять кап dev полностью autosk metadata set <id> cap_overrides.dev 20 # поднять кап dev до 20 autosk metadata unset <id> cap_overrides.dev # вернуть дефолтfalse/null/"off"→ кап отключён; целое ≥0 → новый кап; мусор → безопасный дефолт. Работает без рестарта демона (правка кодаeffectiveCapуже загружена — дальше только метаданные).
Механический гард ролей
Инвариант «dev не трогает тесты, tester пишет только тесты» держится не промптом, а кодом
(src/roleGuard.ts): обёртка шага снимает baseline worktree при входе (HEAD + хэши грязных
файлов), а onTransit — точка, через которую проходит каждый переход, включая MCP-транзиты —
контентно сравнивает состояние на выходе. Нарушение = реджект перехода → харнес отдаёт агенту
kickback («откати эти файлы и повтори переход») + комментарий [role-guard] в задачу.
dev/dev-manual: изменение тестовых файлов запрещено (forbid-tests).tester: изменение файлов вне тестов запрещено (only-tests), КРОМЕ манифестов зависимостей и локфайлов (DEFAULT_TEST_INFRA_PATTERNS: package.json, package-lock.json, pnpm-lock.yaml, go.mod, Cargo.toml, requirements*.txt и т.п.) — добавление тестовой зависимости (например, jsdom) это законная работа tester'а; протаскивание рантайм- зависимости под видом тестовой ловит downstream test-review, который видит дифф.- Что считать тестом — резолвится на входе в шаг, по приоритету:
- закоммиченный конфиг проекта
.hybrid-dev.jsonв корне репозитория:{"testFilePatterns": ["(^|/)qa/", "\\.check\\.ts$"]}(строки-regex; замещают дефолты целиком); - опция
testFilePatternsпри регистрации workflow; DEFAULT_TEST_PATTERNS(jest/vitest/go/pytest/rspec-конвенции). Сам.hybrid-dev.jsonнеприкосновенен для dev/tester независимо от режима — попытка переопределить «что считается тестом» из guarded-роли реджектится тем же гардом. Паттерны фиксируются в baseline на входе, так что правка конфига посреди шага на текущую проверку не влияет.
- закоммиченный конфиг проекта
- Гард fail-open: рестарт демона посреди шага или сбой git не блокируют конвейер
(baseline живёт в памяти демона). Известное следствие: после парковки из-за нарушения
и
resumebaseline пересоздаётся от текущего состояния — человек обязан глянуть комментарий[role-guard]перед resume. - Tester, которому нужно поменять код (например, добавить тестовую зависимость в package.json), будет остановлен гардом — это осознанно: такие случаи идут через human.
Парное ревью
test-review и review — composite-шаги: два read-only ребёнка (claude -p, codex exec --sandbox read-only)
запускаются через Promise.all, возвращают JSON-отчёты; детерминированный синтезатор объединяет находки
(union, с пометкой источника) и делает единственный ctx.transit(). Гейт держат только blocking-находки;
находка с target:"tester" (баг без теста) уводит задачу в tester, а не в dev. Всё логируется в транскрипт
сессии (pair-review:start / :reviewer / :verdict + читаемое сообщение с вердиктом), иначе шаг выглядел
бы пустым (работа идёт через ctx.exec + ctx.comment, минуя session-view).
Разрешение вердикта пары (три исхода):
- единогласный approve → дальше по конвейеру (
approveTarget); - единогласный block (никто не одобрил) → tester (если есть blocking с
target:tester) иначе dev; - split (≥1 approve и ≥1 block по одному вопросу) → арбитраж человека (
status:human), НЕ возврат в tester/dev. Обоснование: split — это спор ревьюеров о severity/суждении, а не пропущенный дефект; автоматический возврат в tester/dev бессмыслен (они не могут разрешить расхождение ревьюеров) и создаёт петлю до исчерпания капа. Строгость AND сохраняется там, где важна: оба должны одобрить, чтобы гейт прошёл. Комментарий split-эскалации содержит позиции обоих ревьюеров, вопрос человеку и куда вернуть задачу черезresume --to.
Установка и запуск
autosk ext add /Users/nikitabogomolov/sites/autosk-hybrid-dev # уже сделано (global)
pkill -x autoskd # после правок кода extension
autosk workflow show hybrid-dev # проверить регистрацию
autosk create "Задача" --workflow hybrid-dev # запуск
autosk resume <id> --to pr # ручной PR после accept
autosk resume <id> --to cleanup # снос worktree после приёмкиРазработка
pnpm install
pnpm test # vitest: граф, гарды onTransit, парсер отчётов, синтезатор
pnpm typecheckПереопределение бинарей детей ревью: AUTOSK_CLAUDE_BIN, AUTOSK_CODEX_BIN.
