Files
orchestrator/docs/architecture/adr/adr-0034-lessons-journal.md
claude-bot 21a47e85d3
All checks were successful
CI / test (push) Successful in 56s
CI / test (pull_request) Successful in 55s
fix(lessons): resolve land-race with ORCH-100 — renumber ADR 0033→0034
Merge-gate auto_rebase_onto_main bounced this branch back: ORCH-100 landed
in main first and claimed global ADR number adr-0033 (adr-0033-sidecar-watchdog),
while this branch had created adr-0033-lessons-journal. Resolved the genuine
land race:

- rebased feature/ORCH-098-fnd onto current origin/main (linear history)
- resolved docs/architecture/README.md component-list conflict — both the
  Lessons-journal and Sidecar-watchdog bullets now coexist
- renamed docs/architecture/adr/adr-0033-lessons-journal.md →
  adr-0034-lessons-journal.md (next free global ADR number) + fixed the
  in-file header
- updated all cross-references (CLAUDE.md, README.md, work-item ADR-001,
  12-review.md) 0033→0034 for the lessons journal; ORCH-100's adr-0033
  (sidecar) left intact
- recovered the ORCH-098 CHANGELOG entry silently dropped by the rebase
  auto-merge (now above ORCH-100, ADR ref corrected to 0034)

No code semantics changed; src/** auto-merged cleanly (ORCH-100 did not
touch src/**). ruff: n/a locally (CI). pytest tests/ -q: 1630 passed.

Refs: ORCH-098
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:44:34 +03:00

7.4 KiB
Raw Blame History

work_item, stage, author_agent, status, created_at, model_used
work_item stage author_agent status created_at model_used
ORCH-098 architecture architect proposed 2026-06-10 claude-opus-4-8

adr-0034: Машинный журнал уроков — таблица lessons + observer-leaf (ORCH-098)

Статус

Proposed

Контекст

Оркестратор автономно ведёт задачи по конвейеру (ORCH-54), но развивается вручную: инциденты → уроки → задачи. Уроки живут свободным текстом в memory/ — не машиночитаемы: нельзя считать паттерны, приоритизировать, предлагать улучшения. ORCH-098 — шаг 1 эпика саморазвития (домен 0 «Фундамент», F2): «топливо» петли самообучения 8A. Нужна структурированная таблица отклонений конвейера, на которой позже встанут ретроспективщик (E2), приоритизатор RICE (E3) и Стрим.

Нормативное требование Славы (10.06): схема ДОЛЖНА сразу нести поля атрибуции урока (platform/project/both/unknown + целевой репо + домен улучшения), иначе позже придётся переделывать схему на живой общей прод-БД.

Кросс-каттинговость (почему сквозной ADR): новый компонент src/lessons.py + аддитивная таблица на общей прод-БД (self-hosting, разделяемой с enduro-trails) + врезки автозаписи в несколько горячих choke-point'ов (stage_engine/merge_gate/launcher) + новый раздел контракта GET /queue. Фундамент для будущих задач-потребителей → регистрируется глобально.

Решение

Журнал уроков — observer (наблюдатель), НЕ Quality Gate. Аддитивная таблица + чистый leaf, по образцу serial_gate/coverage_gate/metrics/bug_fast_track.

  1. Таблица lessons (db.init_db(), CREATE TABLE IF NOT EXISTS + 3 индекса, идемпотентно, restart-safe) — поля контекста (work_item_id/task_id/stage/agent/repo), анализа (root_cause/suggestion), статуса (status/related_task), атрибуции сразу и нуллабельно (attribution/target_repo/target_domain) + source/detail. Без enum-констрейнтов (слаги forward-compatible). Будущие колонки — _ensure_column.

  2. Leaf src/lessons.py (never-raise, импортирует только config+db): record() / get() / update() / snapshot(). Расхождение с гейт-шаблоном: журнал НЕ скоупится по репо — он observer-only и не действует ни на один репо; единственный регулятор — глобальный kill-switch lessons_enabled. Запись урока про enduro ценна и не затрагивает пайплайн enduro (чистая память орка); репо-разрез — на выборке (repo-колонка/фильтр).

  3. Автозапись 4 типов (source="auto", best-effort, дедуп в окне; transient_retry — только на исчерпании бюджета ретраев): gate_failure (stage_engine._handle_qg_failure_rollbacks), merge_hold (merge_gate._handle_merge_verify HOLD), transient_retry (merge-retry/launcher transient budget-exhaustion), deploy_degraded (post-deploy DEGRADED → set_repo_freeze, урок слоя-3 «деплой OK / прод сломан», ET-8). Каждая врезка — одиночный вызов в защитном try/except.

  4. Эндпоинты GET /lessons (read-only, фильтры), POST /lessons (ручная запись, source="manual"), POST /lessons/{id} (update — доклассификация unknown), + read-only ключ "lessons": snapshot() в GET /queue. При выключенном флаге → {"enabled": false}.

Инвариант (нерушимый): STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict-ключи (verdict:/result:/staging_status:/deploy_status:/security_status:/coverage_status:) / схемы существующих таблиц — байт-в-байт не тронуты. Журнал не влияет на продвижение по стадиям.

Композиция с существующими механизмами

  • Self-hosting (общая БД): аддитивная таблица; enduro не затронут (NFR-3).
  • serial-gate (ORCH-088) / post-deploy (ORCH-021): детектор deploy_degraded врезан рядом с set_repo_freeze, не меняя freeze-логику.
  • merge-gate (ORCH-043/071/093): merge_hold/transient_retry читают исход актора, не меняя классификатор/ретрай.
  • metrics (ORCH-099): журнал — историческая память петли (best-effort запись), /metrics — realtime-сырьё для sidecar; разные роли, оба observer-only.

Условность и откат

  • Флаг lessons_enabled (env ORCH_LESSONS_ENABLED, дефолт True; kill-switch) + lessons_dedup_window_s / lessons_query_limit_default. False → полная инертность, нулевая регрессия, конвейер байт-в-байт прежний.
  • never-raise на всех публичных функциях и врезках (NFR-1) — сбой журнала не роняет конвейер.
  • Откат — флаг в false (мгновенно) или revert диффа; таблица не касается существующих.

Последствия

  • + Машиночитаемые уроки — фундамент E2/E3/Стрим; атрибуция forward-proof (без передела живой БД).
  • + Нулевая регрессия; проверенный additive-observer-leaf шаблон → низкий риск; enduro изолирован.
  • Рост таблицы (митигейшн: лёгкие строки + дедуп + budget-exhaustion; ретенция — будущее).
  • Дедуп-запрос в record() (один indexed-SELECT, только auto).

Ссылки

  • Локальный ADR: docs/work-items/ORCH-098/06-adr/ADR-001-lessons-journal.md
  • BRD/TRZ/AC: docs/work-items/ORCH-098/01-brd.md, 02-trz.md, 03-acceptance-criteria.md
  • Data/Infra/Risks: docs/work-items/ORCH-098/08-data-requirements.md, 07-infra-requirements.md, 10-tech-risks.md
  • Эпик: docs/epics/self-evolution.md (домен 0 «Фундамент», F2; петля 8A)
  • Сверено по коду: src/serial_gate.py, src/coverage_gate.py, src/db.py, src/stage_engine.py, src/merge_gate.py, src/agents/launcher.py, src/main.py, src/qg/checks.py.