work_item: ORCH-009
stage: analysis
author_agent: analyst
status: ready-for-review
created_at: 2026-06-10
model_used: claude-opus-4-8
title: "Turnkey-онбординг проектов: kit + скрипт + runbook (ORCH-009)"
framework: pytest
scope: >
  Структурная полнота onboarding-kit, канон 52d/92 шаблонов промптов, материализация
  (плейсхолдеры/утечки), registry round-trip через фактический парсер projects.py,
  планы Plane/Gitea (dry-run, моки), идемпотентность apply, runbook, инварианты src/**.
  Вне покрытия pytest: реальные вызовы Plane/Gitea API и операторский smoke на песочнице
  (AC-13) — выполняется вручную по docs/operations/ONBOARDING.md и протоколируется.
notes: >
  Все тесты детерминированы, без сети (Plane/Gitea мокируются; NFR-5). Точные имена файлов
  тест-модулей могут уточняться архитектором при сохранении покрытия TC↔AC. Полный регресс
  tests/ должен оставаться зелёным (src/** не меняется — NFR-1). Если ADR изменит раскладку
  kit (OQ-1) — пути в тестах следуют ADR, маппинг TC↔AC неизменен.

tests:
  # ---------- AC-1: состав kit ----------
  - id: TC-01
    type: unit
    description: "Kit содержит все элементы FR-1: 6 шаблонов промптов, CLAUDE.md, AGENTS.md, CONTRIBUTING.md, README.md, CHANGELOG.md, docs/ARCHITECTURE.md, docs/PIPELINE.md, docs/PRODUCT_VISION.md, docs/operations/INFRA.md, docs/architecture/adr/, docs/work-items/, docs/history/, .env.example"
    module: tests/test_onboarding_kit.py
    expected: PASS

  - id: TC-02
    type: unit
    description: "Материализация добавляет live-копии docs/_templates/ (16 канонических скелетов) и docs/_standards/ (3 стандарта) из живого канона репо орка; вторая редактируемая копия канона в kit отсутствует (BR-2)"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-2: канон промптов 52d/92 ----------
  - id: TC-03
    type: unit
    description: "Каждый из 6 шаблонов промптов содержит 5 обязательных XML-секций в нормативном порядке context→task→deliverables→constraints→output_format"
    module: tests/test_onboarding_kit.py
    expected: PASS

  - id: TC-04
    type: unit
    description: "Шаблоны developer/reviewer/tester содержат секцию <escalation>; запреты оформлены в формате '❌ → ✅'"
    module: tests/test_onboarding_kit.py
    expected: PASS

  - id: TC-05
    type: unit
    description: "Каждый шаблон промпта направляет агента к доке: читай паспорт(CLAUDE.md)/AGENTS.md/ARCHITECTURE/ADR перед работой; пиши артефакты в docs/work-items/<id>/ по PIPELINE_DOCS; обновляй CHANGELOG/доку"
    module: tests/test_onboarding_kit.py
    expected: PASS

  - id: TC-06
    type: unit
    description: "Шаблоны эмитят 6-польную frontmatter-схему 52c (work_item/stage/author_agent/status/created_at/model_used); machine-verdict ключи ролей байт-в-байт (verdict:/result:/staging_status:/deploy_status:/security_status:); примеры дат/моделей — плейсхолдеры, не литералы (анти-паттерн ORCH-092)"
    module: tests/test_onboarding_kit.py
    expected: PASS

  # ---------- AC-3: reviewer-gate ----------
  - id: TC-07
    type: unit
    description: "Шаблон reviewer.md содержит обязательный gate: документация не обновлена в PR → verdict: REQUEST_CHANGES"
    module: tests/test_onboarding_kit.py
    expected: PASS

  # ---------- AC-4: языковая политика ----------
  - id: TC-08
    type: unit
    description: "Языковая раскладка шаблонов соответствует политике ADR (дефолт: 5 ru + deployer en, канон ADR-001 D2 ORCH-092)"
    module: tests/test_onboarding_kit.py
    expected: PASS

  # ---------- AC-5: материализация ----------
  - id: TC-09
    type: unit
    description: "Рендер kit с тестовыми параметрами подставляет все плейсхолдеры: в выходе нет ни одного неразрешённого плейсхолдера (grep по синтаксису из ADR)"
    module: tests/test_onboarding_script.py
    expected: PASS

  - id: TC-10
    type: unit
    description: "В отрендеренном kit нет утечек орк-специфики, где должен быть параметр: префикс ORCH- вместо префикса проекта, порты 8500/8501, self-hosting-правила орка"
    module: tests/test_onboarding_script.py
    expected: PASS

  - id: TC-11
    type: unit
    description: "Ссылочная целостность: каждый путь, на который ссылаются отрендеренные промпты и AGENTS.md, существует в материализованном каркасе"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-6: registry round-trip ----------
  - id: TC-12
    type: integration
    description: "Сгенерированная скриптом запись реестра парсится фактическим projects._parse_projects_json; ProjectConfig несёт исходные plane_project_id/repo/work_item_prefix/name; существующие записи реестра сохранены без искажений"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-7: план Plane ----------
  - id: TC-13
    type: unit
    description: "plan-режим: план Plane содержит все канонические имена статусов _PLANE_NAME_TO_KEY (включая 'Confirm Deploy' и 'STOP' с группой cancelled) байт-в-байт и лейблы autoApprove/autoDeploy/Bug"
    module: tests/test_onboarding_script.py
    expected: PASS

  - id: TC-14
    type: unit
    description: "Шаг Plane, недоступный через API (мок отвечает отказом/не реализовано), помечается в плане/отчёте как manual-step со ссылкой на runbook — не отбрасывается молча и не валит скрипт"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-8: план Gitea + dry-run ----------
  - id: TC-15
    type: unit
    description: "plan-режим: план Gitea содержит создание репо, webhook (events push/pull_request/status + HMAC-secret вне гита) и initial push kit в свежесозданный репо"
    module: tests/test_onboarding_script.py
    expected: PASS

  - id: TC-16
    type: unit
    description: "dry-run (plan) не выполняет ни одной мутации: ноль POST/PUT/DELETE в замоканных клиентах Plane/Gitea, ноль git push, ноль записей на диск вне отчёта"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-9: идемпотентность / безопасность apply ----------
  - id: TC-17
    type: integration
    description: "Повторный apply на уже созданном проекте (моки: репо/webhook/статусы/лейблы существуют): сущности распознаны и помечены skipped(exists); нет дублей, удалений и перезаписи без явного флага; итоговый отчёт перечисляет created/skipped/manual-step"
    module: tests/test_onboarding_script.py
    expected: PASS

  - id: TC-18
    type: unit
    description: "Скрипт не содержит операций рестарта/останова контейнеров, правки прод-.env и push в существующие репо: на моках полного прогона apply такие вызовы отсутствуют (NFR-2)"
    module: tests/test_onboarding_script.py
    expected: PASS

  # ---------- AC-10: INFRA.md шаблон ----------
  - id: TC-19
    type: unit
    description: "Шаблон INFRA.md kit содержит обязательные секции: топология (контейнеры/порты прод+staging/сеть/тома/БД), карта env + правило секретов (.env на хосте, .env.example — канон), границы доступа, риски общего хоста"
    module: tests/test_onboarding_kit.py
    expected: PASS

  # ---------- AC-11: runbook ----------
  - id: TC-20
    type: unit
    description: "ONBOARDING.md покрывает все слои в последовательности: предусловия → Plane → Gitea → kit → регистрация (env + операторский управляемый рестарт с self-hosting-предупреждением) → верификация (verify + smoke) → откат; ручные шаги помечены и снабжены командами проверки"
    module: tests/test_onboarding_kit.py
    expected: PASS

  # ---------- AC-12: инварианты ----------
  - id: TC-21
    type: unit
    description: "Снапшот STAGE_TRANSITIONS и реестра QG_CHECKS совпадает с эталоном (src/** не затронут логикой онбординга); эталонные промпты .openclaw/agents/ орка не изменены задачей"
    module: tests/test_onboarding_invariants.py
    expected: PASS

  - id: TC-22
    type: integration
    description: "Полный регресс существующего tests/ остаётся зелёным после добавления onboarding-артефактов (никакой новый импорт/код не ломает конвейер)"
    module: tests/
    expected: PASS
