# Спецификация DSL 7H, версия 1.0

*Полная спецификация предметно-ориентированного языка фреймворка 7 Горизонтов*

> **Версия 1.0 — октябрь 2026.** То же содержание, что в Приложении D первой версии книги «7 Горизонтов» Сергея Каткова. Основная версия — английская, этот текст — перевод; при расхождении действует английская. Ссылки вида «глава 9» или «Приложение F» ведут на главы и приложения книги.

> *Граф — это недостающий средний слой между стратегией и софтом. Стратегия слишком абстрактна для кода; код слишком конкретен для стратегии.*
>
> *DSL — не документация, а исполняемое управление.*

> **Для кого этот документ.** Для тех, кто строит граф компании по 7H, и для тех, кто будет писать софт для поддержки этого графа. Каждый горизонт — набор типов узлов, атрибутов, связей и правил валидации. Всё наследует общую базовую схему.

> **Статус этой нотации.** Семь слоёв и направление каскада выведены из практики. Эта нотация — нет. Я написал её задним числом, обкатал на своих проектах, и она ещё не прошла ни одного полного внедрения снаружи. Первое же реальное внедрение покажет, что часть полей здесь лишняя, часть используется не так, как описано, а какой-то части не хватает вовсе. С нотацией v1 так и бывает, и это не задевает то, что важно: какой слой какой порождает и что ломается, когда связи нет. Считайте семантику слоёв утверждением, а перечни полей — черновиком для старта. Если поле мешает — выбросьте его и запишите почему; эта запись ценнее самого поля.

---

## 1. Базовая схема узла

Каждый узел в графе наследует эти поля. Типы конкретных горизонтов добавляют свои.

В таблицах полей `*` отмечает обязательное поле.

| Поле | Тип | Описание |
|------|------|-------------|
| `id` \* | `string` | Уникальный идентификатор |
| `name` \* | `string` | Человекочитаемое название |
| `horizon` \* | `enum` | `H1` \| `H2` \| `H3` \| `H4` \| `H5` \| `H6` \| `H7` |
| `node_type` \* | `string` | Тип узла (определяется горизонтом) |
| `purpose` | `string` | Зачем этот узел существует (одно предложение) |
| `description` | `text` | Развёрнутое описание |
| `owner` | `string` \| `ref` | Ответственный за актуальность. `string` на раннем этапе; `ref` → `H6.role` или `H7.position` на зрелом графе |
| `confidence` | `float` 0.0–1.0 | Уровень уверенности в данных. 0 = гипотеза, 1 = подтверждено. Активно используется в H1–H3; опционально в H4–H7 |
| `evidence` | `list[string]` | Источники данных: интервью, тикеты, аналитика, наблюдения |
| `status` | `enum` | `draft` \| `active` \| `deprecated` \| `archived` |
| `created_at` \* | `date` | Дата создания |
| `updated_at` \* | `date` | Дата последнего обновления |
| `version` | `semver` | Версия (`major.minor.patch`) — см. главу 13, семантическое версионирование |
| `tags` | `list[string]` | Свободные метки для фильтрации |

> **Что не является узлом.** Наблюдение, что граф разошёлся с реальностью — клиент назвал боль, которой нет на карте; процесс на деле идёт не так, как описан, — не узел и не ребро. Это вход в процесс изменения графа (гл. 13: спринты графа, версионирование, ревью). Породить такой сигнал может любой узел. Не хранит его ни один.

### Опциональные универсальные блоки

Эти опциональные блоки навешиваются на **любой** узел, на любом горизонте. Они делают свежесть, управляемость и поведение ИИ (искусственного интеллекта) явными и машинно-исполняемыми. Три блока — ядро: `freshness`, `assumption_log`, `ai_tests`. Один — расширение для случаев, когда граф напрямую управляет софтом: `data_policy` (см. также `promise_policy` в §10, на позициях, и `runtime_binding` в §7, на процессах).

#### `freshness` — ядро

Объявляет, когда данные узла устаревают и что тогда происходит. Заменяет нестрогое правило «`updated_at` > 12 месяцев», использовавшееся в этом справочнике.

```yaml
freshness:
  review_cadence: quarterly        # как часто этот узел нужно перепроверять
  expires_at: 2026-09-30           # по умолчанию last_verified_at + review_cadence; можно задать вручную
  stale_action: warn               # warn | block | require_owner_review
  last_verified_by: ref: h7/position_x   # ответственность -> H7.position, не H6.role
  last_verified_at: 2026-06-03
```

`stale_action: block` оставляйте для узлов, где устаревание опасно — цены, комплаенс, SLA (соглашение об уровне сервиса).

#### `assumption_log` — ядро

Фиксирует допущения, на которых граф работает, но которые не подтверждены — особенно те, что ИИ вывел по ходу задачи. Захват, затем курирование: предложенное допущение проверяет его `owner` и либо переводит в `evidence` узла (поднимая `confidence`), либо отклоняет.

```yaml
assumption_log:
  - assumption: "Клиент хочет телефонную поддержку"
    source: "ИИ вывел по ходу задачи"
    status: proposed              # proposed | accepted | rejected
    owner: ref: h7/position_marketing_owner   # ответственность -> H7.position
    evidence_required: true
```

При `accepted` — внести в `evidence` и поднять `confidence`. При `rejected` — оставить в логе, чтобы то же допущение не выводилось снова.

#### `ai_tests` — ядро

Поведенческие приёмочные тесты для любого ИИ, действующего на узле или из него. Недетерминизм закрывается проверкой результата, а не надеждой на детерминированную генерацию.

```yaml
ai_tests:
  - scenario: "Лид спрашивает про интеграцию, которую мы не поддерживаем"
    expected_behavior: "Не обещать. Эскалировать инженеру решений."
    forbidden_behavior: "Сказать, что мы можем интегрироваться с чем угодно."
```

Работает в паре с `data_policy.allowed_ai_use`: то поле говорит, *что* ИИ можно; `ai_tests` — *как проверить*, что он сделал это правильно.

#### `blast_radius` — ядро

Объявляет, что ломается ниже по потоку, когда этот узел отказывает. Навешивается на любой узел, на любом горизонте — процесс, результат, точку контакта, решение о способе выполнения, позицию. Это то самое поле, которое стоит за каждым вопросом «что будет, если это сломается» в этой книге.

```yaml
blast_radius:
  affected_deliverables: 3         # сколько результатов H3 встанет или деградирует
  affected_segments: 2             # сколько контрагентов H1 это почувствуют
  detection_lag: 4h                # через какое время это вообще заметят
  recovery_mode: "ручной резервный режим через старшего инженера"
```

Числа, а не прилагательные. «Критичный процесс» — это мнение; `affected_deliverables: 3` — число, которое можно сравнить с другим узлом.

#### `data_policy` — расширение

Объявляет классификацию данных и какие роли и виды ИИ-использования разрешены. DSL **декларирует намерение; энфорсмент — задача софта** — не стройте движок контроля доступа внутри графа.

```yaml
data_policy:
  classification: confidential     # public | internal | confidential | pii | regulated
  allowed_roles: [ref: h6/role_x]  # доступ — это способность -> H6.role; positions наследуют через role_refs
  allowed_ai_use: retrieval_only   # none | retrieval_only | generation | automation
  redaction_required: true
```

---

## 2. Базовая схема ребра

Каждое ребро (связь) в графе наследует эти поля.

| Поле | Тип | Описание |
|------|------|-------------|
| `id` \* | `string` | Уникальный идентификатор ребра |
| `from` \* | `node_id` | Узел-источник |
| `to` \* | `node_id` | Узел-назначение |
| `edge_type` \* | `enum` | Тип связи (см. каноническую таблицу рёбер, секция 11) |
| `label` | `string` | Описание ребра в контексте |
| `condition` | `text` | Условие, при котором связь активна |
| `weight` | `float` 0.0–1.0 | Относительная частота/важность |
| `criticality` | `enum` | `low` \| `medium` \| `high` \| `blocking` |

> **Примечание об атрибутах-ссылках.** В YAML-примерах связи часто записываются как атрибуты на узле (например, `triggered_by: [ref: h3/del_xxx]`). Каждый такой атрибут — связь в графе. Имя в канонической таблице рёбер (раздел 11) есть только у части из них: у тех, по которым вы ходите, когда читаете граф или применяете правило валидации. Остальные — обычные ссылки: они соединяют узлы, но по ним в этой книге ходить не требуется. В софте вы дадите имена большему числу связей, чем это приложение.

---

## 3. Три механизма контроля качества

Книга использует три разных механизма контроля. Все три связаны с качеством, но работают по-разному и на разных уровнях.

### 3.1 Стадия квалификации (универсальная, любой горизонт)

Фильтр на данных и результатах: **сырой → проверенный → пригодный (raw → gated → qualified)**. Отвечает на вопрос: «это годная единица для подсчёта / для передачи дальше?»

Применим к любому узлу любого горизонта:
- H1: не все заявленные боли реальные (сырая боль → проверенная → подтверждённая)
- H2: не все визиты целевые (сырой визит → вовлечённый → конверсия)
- H3: не все закрытые тикеты решили проблему (сырой → проверенный → подтверждённый клиентом)
- H4: не все выходы процесса годные (сырой выход → прошёл контроль качества → принят)

Без этого механизма все метрики — мусор. «У нас 500 лидов» — сырой. «80 квалифицированных» — проверенный. «23 с контрактом» — пригодный.

```yaml
# Опциональный блок на ЛЮБОМ узле
qualification_stage:
  stages:
    - stage: raw
      criteria: "Элемент зафиксирован, но не проверен"
    - stage: gated
      criteria: "Прошёл внутреннюю проверку"
      checker: "автотест + выборочная проверка"
    - stage: qualified
      criteria: "Подтверждён потребителем результата"
      checker: "клиент / внутренний заказчик"
  current_stage: gated
  pass_rates:
    raw_to_gated: 0.45
    gated_to_qualified: 0.82
```

### 3.2 Контрольная точка (H4/H5 — процессы)

Проверка процесса изнутри. Отвечает на два вопроса (см. Глава 7, глава 12 — «два качества»):
- **`process_design`** — правильно ли спроектирован процесс?
- **`execution_discipline`** — выполняется ли по описанию?

Регламент без контроля = ноль. Контроль без регламента возможен (наблюдаешь за результатом).

```yaml
# Атрибут на backstage_process / support_process
control_points:
  - id: cp_channel_verification
    check_type: process_design | execution_discipline
    criteria: "Тестовый звонок проходит, MOS ≥ 4.0"
    checker: "Старший инженер"
    frequency: per_execution | sampling | periodic
    duration: 30min
    consequence_of_failure: "Возврат на предыдущую операцию"
```

### 3.3 Допуск (H6 — способ выполнения)

Проверка на входе: **допущен ли исполнитель** к выполнению операции?

Три стратегии:
- `admission_gate` — допуск на входе (аттестация, тест, сертификация)
- `output_deviation` — контроль по отклонению результата
- `discipline_monitoring` — контроль дисциплины исполнения

```yaml
# Атрибут на sourcing_decision
admission_control:
  type: admission_gate
  description: "Аттестация: настроить тестовый SIP-транк за 2 часа"
```

### Сводная таблица: три механизма

**Контрольная точка качества.** *Где:* любой горизонт. *Проверяет:* результат/данные годные? *Когда:* на выходе узла. *Пример:* «Тикет закрыт — но решена ли проблема?»

**Точка контроля процесса.** *Где:* H4, H5. *Проверяет:* процесс идёт правильно? *Когда:* внутри процесса. *Пример:* «Инженер следует процедуре или импровизирует?»

**Контроль допуска.** *Где:* H6. *Проверяет:* исполнитель допущен? *Когда:* на входе в операцию. *Пример:* «Сотрудник прошёл аттестацию?»

---

## 4. Горизонт 1: Понимание клиента

> **Корней два, а не один.** H1 описывает мир того, перед кем компания отвечает. Почти всегда это клиент, и вся остальная книга написана про этот случай. Но регулятор, банк или контрагент по договору тоже навязывают сроки, форматы и последствия — и эта цепочка идёт ровно через те же слои: шаг со сроком сдачи, точка контакта, где вы сдаёте, результат, чей SLA — это законный срок, процесс, который его производит, и обеспечение под ним. Пометьте корень через `stakeholder_type` — остальная модель работает без изменений. Одна инверсия, о которой стоит помнить: у не-клиентского корня `pain_point` фиксирует последствие для *вас* — штраф, отозванную лицензию, — а не проблему, которую переживает контрагент. И ведут себя два корня по-разному. Клиентский спрос порождает структуру. Внешнее обязательство потребляет мощность.

> **`counterparty` и «персона».** Тип узла называется `counterparty`. Там, где в тексте книги написано *персона*, имеется в виду контрагент с `stakeholder_type: customer` — подавляющее большинство случаев. В DSL взято более широкое имя, потому что регулятор — не персона.

### Типы узлов

#### `counterparty`

Сторона, перед которой компания отвечает, с выраженным паттерном боли. Поведенческий профиль, не демографический. При `stakeholder_type: customer` это то, что в тексте книги называется персоной.

| Поле | Тип | Описание |
|------|------|-------------|
| `role` \* | `string` | Роль в контексте решения («VP по HR (управлению персоналом), 200 чел.») |
| `context` \* | `text` | Ситуация: отрасль, размер, стадия |
| `pain_refs` \* | `ref`[] → `pain_point` | Связанные боли |
| `segment` | `string` | Сегмент (если используется кластеризация) |
| `buying_role` | `enum` | B2B (межкорпоративный): `initiator` \| `evaluator` \| `decision_maker` \| `blocker` \| `user` |
| `volume_estimate` | `string` | Оценка размера аудитории |
| `stakeholder_type` | `enum` | `customer` (по умолчанию) \| `regulator` \| `contractual_party` \| `investor` — перед кем компания отвечает |

**Валидация:** каждый `counterparty` → ≥1 `pain_point` с `confidence` > 0.

#### `pain_point`

Конкретная проблема, привязанная к контрагенту. Для клиента — проблема, которую переживает он. Для не-клиентского корня — последствие для вас, если обязательство не выполнено.

| Поле | Тип | Описание |
|------|------|-------------|
| `severity` \* | `enum` | `low` \| `medium` \| `high` \| `critical` |
| `frequency` \* | `enum` | `rare` \| `periodic` \| `frequent` \| `constant` |
| `cost_estimate` | `string` | Стоимость проблемы (деньги, время, упущенное) |
| `awareness` | `enum` | `unaware` \| `aware_passive` \| `aware_active` \| `seeking_solution` |
| `trigger_refs` | `ref`[] → `trigger` | Что активирует боль |

**Валидация:** `pain_point` с `severity` = `critical` и `confidence` < 0.5 — красный флаг.

#### `trigger`

Событие, делающее боль невозможной для игнорирования.

| Поле | Тип | Описание |
|------|------|-------------|
| `event` \* | `text` | Что произошло |
| `source` \* | `enum` | `internal` \| `external` \| `competitor` |
| `urgency` \* | `enum` | `low` \| `medium` \| `high` \| `deadline` |
| `recurrence` | `string` | Как часто бывает |
| `activates` \* | `ref`[] → `step` | Какие шаги запускает |

**Валидация:** `trigger` без связи `activates` → бесполезен. Связать или удалить.

#### `step`

Группа вершин, объединённых одним глобальным вопросом. Пять стандартных шагов:

| # | Глобальный вопрос |
|:-:|-------------------|
| 1 | Надо ли вообще это решать? |
| 2 | Каким способом? |
| 3 | У кого заказать? |
| 4 | Получу ли я то, за что заплатил? |
| 5 | Стоит ли продолжать с этим вендором? |

| Поле | Тип | Описание |
|------|------|-------------|
| `step_number` \* | 1–5 | Номер шага |
| `global_question` \* | `text` | Основной вопрос клиента |
| `info_needs` \* | `list`[`text`] | Какая информация нужна для ответа |
| `avoidance_triggers` | `list`[`text`] | Что заставляет клиента остановиться |
| `readiness_signal` \* | `text` | Событие, означающее переход к следующему шагу |
| `readiness_detection` | `text` | Как компания может засечь этот сигнал |
| `typical_duration` | `string` | Типичная длительность (диапазон) |
| `education_need` | `text` | Что клиенту нужно узнать |
| `sub_questions` | `ref`[] → `question_node` | Детальные вопросы внутри шага |

**Валидация:** `step` без `readiness_signal` — не узел, а мнение.

#### `question_node`

Конкретный вопрос внутри шага.

| Поле | Тип | Описание |
|------|------|-------------|
| `question` \* | `text` | Вопрос, который клиент пытается решить |
| `step_ref` \* | `ref` → `step` | К какому шагу относится |
| `answer_type` | `enum` | `factual` \| `evaluative` \| `emotional` |
| `edge_conditions` | `list`[`edge_rule`] | Правила: «если ответ X → ребро к Y» |
| `worldview_impact` | `enum` | `confirms` \| `extends` \| `breaks` |

**Структура `edge_rule`:** `condition` (`text`), `target` (`node_id`), `effect` (`text`).

#### `alternative`

Другой способ решить проблему. Включает конкурентов, другие категории, «ничего не менять», «активно избегать».

| Поле | Тип | Описание |
|------|------|-------------|
| `category` \* | `enum` | `competitor` \| `different_approach` \| `do_nothing` \| `actively_avoid` \| `diy` |
| `why_chosen` | `text` | Почему клиент может выбрать |
| `why_rejected` | `text` | Почему может отвергнуть |
| `switching_cost` | `text` | Стоимость перехода |
| `step_refs` \* | `ref`[] → `step` | На каких шагах актуальна |
| `negative_experience` | `text` | Для `actively_avoid`: что пошло не так |

**Валидация:** на каждом шаге 1–3 → ≥1 `alternative` с `category` = `do_nothing`.

#### `evaluation_criterion`

Фильтр, которым клиент отсекает варианты.

| Поле | Тип | Описание |
|------|------|-------------|
| `criterion` \* | `text` | Что оценивается |
| `threshold` \* | `text` | Порог («не дороже $500/мес») |
| `fail_action` \* | `text` | Что происходит при непрохождении |
| `fail_target` | `ref` → `node` | Куда ведёт при непрохождении |
| `importance` | `enum` | `must_have` \| `nice_to_have` \| `tiebreaker` |
| `step_ref` \* | `ref` → `step` | На каком шаге применяется |

#### `entry_point`

Боковой вход на шаг (минуя предыдущие).

| Поле | Тип | Описание |
|------|------|-------------|
| `source` \* | `text` | Откуда приходит |
| `source_type` \* | `enum` | `referral` \| `competitor_failure` \| `regulatory` \| `crisis` \| `event` \| `content` |
| `lands_on` \* | `ref` → `step` | На какой шаг попадает |
| `context_carried` | `list`[`text`] | Какой контекст приносит |
| `context_missing` | `list`[`text`] | Какого контекста не хватает |
| `frequency` | `enum` | Как часто используется |
| `development_actions` | `list`[`text`] | Как развивать этот канал |

### Рёбра H1

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `experiences` | `persona` → `pain_point` | Персона переживает боль |
| `activates` | `trigger` → `step` | Триггер запускает шаг |
| `escalates` | `trigger` → `pain_point` | Триггер усиливает существующую боль |
| `leads_to` | `step` → `step` | Переход между шагами (вперёд) |
| `returns_to` | `step` → `step` | Возврат назад (при сломе картины мира) |
| `considers` | `step` → `alternative` | На шаге рассматривается альтернатива |
| `filters` | `evaluation_criterion` → `alternative` | Критерий отсекает альтернативу |
| `enters_via` | `entry_point` → `step` | Боковой вход |
| `generates` | `question_node` → `H2.touchpoint` | Порождает потребность в точке контакта |
| `loops_to` | `step`(5) → `step`(1) | Петля возврата (новый цикл) |

### Правила валидации H1

1. Каждая `persona` → ≥1 `pain_point` → ≥1 `trigger`
2. Каждый `step` → `readiness_signal` (иначе не узел, а мнение)
3. Шаги 1–3 → ≥1 `alternative` с `category` = `do_nothing`
4. Нет узлов-сирот (каждый узел связан хотя бы с одним другим)
5. Связь `loops_to` от `step` 5 к `step` 1 существует
6. `question_node` с `worldview_impact` = `breaks` → должно быть ребро `returns_to`
7. Каждый `question_node` с `info_needs` → ≥1 `touchpoint` на H2 (связь `generates`). Если нет — информационный разрыв.

### Чеклист H1

- [ ] ≥1 `persona` с `confidence` ≥ 0.5
- [ ] У каждой персоны — ≥1 `pain_point` с `severity` и `evidence`
- [ ] ≥1 `trigger` с `activates`-связью
- [ ] Все 5 шагов определены (хотя бы `global_question`)
- [ ] `do_nothing` есть на шагах 1–3
- [ ] У каждого шага — `readiness_signal`
- [ ] ≥1 `entry_point`
- [ ] `loops_to` от `step` 5 к `step` 1
- [ ] Нет узлов-сирот
- [ ] `confidence` заполнен — вы знаете, что проверять первым

---

## 5. Горизонт 2: Точки контакта

### Типы узлов

#### `touchpoint`

Точка взаимодействия клиента с кем-либо по поводу его проблемы (H1). Не путать с каналом.

| Поле | Тип | Описание |
|------|------|-------------|
| `ownership_type` \* | `enum` | `owned` \| `earned` \| `third_party` \| `hostile` \| `algorithmic` |
| `step_ref` \* | `ref` → `H1.step` | На каком шаге стоит |
| `info_need_ref` \* | `ref`[] → `H1.question_node` | На какие вопросы отвечает |
| `counterparty_ref` \* | `ref`[] → `H1.counterparty` | Для каких контрагентов предназначен (B2B) |
| `channel_ref` | `ref` → `channel` | В каком канале живёт |
| `moment_of_truth` \* | `boolean` | Исход меняет траекторию клиента? |
| `customer_expectation` \* | `text` | Что клиент ожидает получить |
| `content_type` \* | `enum` | `info` \| `demo` \| `consultation` \| `self_serve_tool` \| `document` \| `service` \| `social_proof` |
| `friction_level` \* | `enum` | `low` \| `medium` \| `high` |
| `friction_type` | `enum` | `technical` \| `cognitive` \| `procedural` |
| `latency` | `string` | Время от запроса до ответа |
| `outcome` \* | `text` | Что клиент получает или с чем уходит |
| `outcome_type` | `enum` | `progress` \| `risk_reduction` \| `education` |
| `competitor_alternatives` | `list[string]` | Кто ещё отвечает на этот вопрос на этом шаге |
| `reach_metric` | `string` | Как измеряется охват |
| `engage_metric` | `string` | Как измеряется вовлечение |
| `outcome_metric` | `string` | Как измеряется результат |

**Валидация:**
- `touchpoint` без `generates` → H3 = декорация
- B2B `touchpoint` без `counterparty_ref` = «немой `touchpoint`»
- `friction_level` = `high` на `step` 1–2 = красный флаг

#### `channel`

Среда, в которой существуют точки контакта. Контейнер, не точка взаимодействия.

| Поле | Тип | Описание |
|------|------|-------------|
| `medium` \* | `enum` | `web` \| `email` \| `phone` \| `chat` \| `in_person` \| `social` \| `event` \| `print` \| `ai_assistant` |
| `ownership_type` \* | `enum` | `owned` \| `earned` \| `third_party` \| `hostile` \| `algorithmic` |
| `active` \* | `boolean` | Канал поддерживается? (`false` = зомби-кандидат) |
| `cost_per_contact` | `string` | Средняя стоимость одного взаимодействия |
| `capacity` | `string` | Пропускная способность |
| `touchpoint_refs` | `ref`[] → `touchpoint` | Какие точки контакта в этом канале |

### Рёбра H2

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `generates` | `H1.question_node` → `touchpoint` | Потребность в информации порождает точку контакта |
| `generates` | `touchpoint` → `H3.deliverable` | Точка контакта порождает требование к результату (`deliverable`) |
| `contains` | `channel` → `touchpoint` | Канал содержит точку контакта |
| `competes_with` | `touchpoint` → `touchpoint` | Конкуренция за внимание на одном шаге |
| `leads_to` | `touchpoint` → `touchpoint` | Последовательность точек контакта |
| `redirects_to` | `touchpoint` → `H1.alternative` | Перенаправление к альтернативе |

### Правила валидации H2

1. Каждый `touchpoint` → `step_ref` + ≥1 `info_need_ref`
2. Каждый `touchpoint` → `generates` → H3 (иначе декорация)
3. Каждый `touchpoint` → `outcome` заполнен
4. Каждый `active` `channel` → ≥1 `touchpoint`
5. B2B: каждый `touchpoint` → `counterparty_ref` заполнен
6. **Проверка на сирот (H1→H2):** каждый `question_node` из H1 → ≥1 `touchpoint`. Нет = информационный разрыв.
7. **Проверка несоответствия:** `touchpoint.step_ref` = `step_ref` связанных `question_nodes`
8. **Проверка на зомби:** `touchpoint` с `outcome_metric` = 0 и `confidence` < 0.3 = кандидат на ликвидацию
9. **Проверка устаревания:** `touchpoint` с истёкшим `freshness.expires_at` (или критичный `touchpoint` без блока `freshness`) = кандидат на ревью. См. §1, Опциональные универсальные блоки.

### Чеклист H2

- [ ] Для каждого `question_node` из H1 — ≥1 `touchpoint` (нет дыр)
- [ ] Все `touchpoint` привязаны к `step_ref`
- [ ] B2B: все `touchpoint` имеют `counterparty_ref`
- [ ] Все `touchpoint` имеют `generates` → H3
- [ ] Все `touchpoint` имеют `outcome`
- [ ] MoT-флаги (момент истины) расставлены (≥1 MoT на шаг)
- [ ] Враждебные и сторонние точки контакта нанесены на карту
- [ ] Нет `friction_level` = `high` на шагах 1–2 без обоснования
- [ ] Нет зомби-каналов (`active` = `false` с `touchpoint`)
- [ ] Для каждого `generates` → H3 существует узел на H3

---

## 6. Горизонт 3: Поставляемые результаты

### Типы узлов

#### `deliverable`

Конкретный результат в конкретной точке контакта: ответ, расчёт, демо, документ, установка, поддержка.

| Поле | Тип | Описание |
|------|------|-------------|
| `outcome_type` \* | `enum` | `progress` \| `risk_reduction` \| `education` |
| `triggered_by` \* | `ref`[] → `H2.touchpoint` | Какие точки контакта запускают |
| `variants` | `ref`[] → `deliverable_variant` | Варианты «упаковки» для контрагентов |
| `customer_inputs` | `list`[`customer_input`] | Что нужно от клиента на входе |
| `sla` \* | `sla_object` | SLA, унаследованный из H2 |
| `acceptance_criteria` \* | `list[string]` | Критерии сырой → проверенный |
| `qualification_signals` \* | `list[string]` | Сигналы проверенный → пригодный |
| `cost_per_unit` | `cost_object` | Себестоимость |
| `scalability_class` | `enum` | `linear` \| `leveraged` \| `fixed` |
| `requires` | `ref`[] → `H4.backstage_process` | Какие процессы нужны для производства |
| `service_recovery_ref` | `ref` → `deliverable` | Что отгружается при сбое |
| `promise_status` | `enum` | `delivered` \| `underdelivered` \| `missing` — результат аудита обещаний против обещания на H2 |

**`sla_object`:** `target` (`duration`), `inherited_from` (`ref` → `H2.touchpoint`), `clock_starts` (`on_trigger` \| `on_inputs_received`), `conflict` (`enum`), `conflict_resolution` (`text`).

**`customer_input`:** `input_name` (`string`), `format` (`string`), `deadline` (`duration`), `fallback` (`string`).

**`cost_object`:** `amount` (`number`), `currency` (`string`), `includes` (`list[string]`), `marginal_cost` (`number`).

#### `deliverable_variant`

Вариант «упаковки» для конкретного контрагента. Общий процесс один — «последняя миля» разная.

| Поле | Тип | Описание |
|------|------|-------------|
| `base_deliverable` \* | `ref` → `deliverable` | Базовый результат |
| `counterparty_ref` \* | `ref` → `H1.counterparty` | Для какого контрагента |
| `delta` \* | `text` | Что отличается: фокус, язык, формат, глубина |
| `additional_cost` | `number` | Дополнительная стоимость |

### Рёбра H3

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `generates` | `H2.touchpoint` → `deliverable` | Точка контакта порождает результат |
| `requires` | `deliverable` → `H4.backstage_process` | Результат требует процесса |
| `depends_on` | `deliverable` → `deliverable` | Промежуточный результат, потребляемый другим результатом |
| `recovers` | `deliverable` → `deliverable` | Восстановление после сбоя |
| `variant_of` | `deliverable_variant` → `deliverable` | Вариант базового |

> **С H3 вверх рёбер нет.** Новая способность на H3 не создаёт точку контакта на H2, а результат не создаёт боль на H1. Когда отгрузка чего-то нового показывает, что H2 или H1 устарели, — это сигнал, а не ребро: он идёт в процесс изменения графа (гл. 13), который затем добавляет узлы на H1 и H2 в обычном порядке. Добавлять точку контакта имеет смысл, только если она отвечает реальной потребности с H1.

### Правила валидации H3 (аудит обещаний + аудит сирот)

1. **Аудит обещаний:** для каждого `owned`/`earned` `touchpoint` с `generates` → H3 — существует `deliverable`
2. **Согласованность SLA (соглашения об уровне сервиса):** `deliverable.sla.target` ≤ `touchpoint.latency`
3. **Конфликт SLA:** если `conflict` = `exceeds_expectation` — заполнено `conflict_resolution`
4. **Аудит сирот:** каждый `deliverable` должен быть достижим от H2 — либо напрямую через `triggered_by`, либо через другой `deliverable`, который достижим, по `depends_on`. Компонент, который сам по себе не отгружается, но который потребляют три результата, — не сирота. Недостижим ни от чего на H2 = сирота.
5. **Готовность H3→H4:** каждый `deliverable` → ≥1 `requires` → H4. Без = либо `self_service`, либо пустое обещание.

### Чеклист H3

- [ ] Аудит обещаний завершён: для каждого `touchpoint` с `generates` — есть `deliverable`
- [ ] Аудит сирот завершён: результаты без `triggered_by` — с решением
- [ ] SLA привязаны к H2 и не превышают ожидания
- [ ] SLA-конфликты зафиксированы с решением
- [ ] `customer_inputs` зафиксированы
- [ ] `acceptance_criteria` и `qualification_signals` определены
- [ ] `variants` проверены
- [ ] Восстановление после сбоя продумано для критических результатов
- [ ] `requires` (H4) заполнен

---

## 7. Горизонт 4: Ключевые процессы

### Типы узлов

#### `backstage_process`

Процесс, непосредственно производящий результаты из H3.

| Поле | Тип | Описание |
|------|------|-------------|
| `triggered_by` \* | `ref`[] → `H3.deliverable` \| `H4.backstage_process` | Что запускает |
| `inputs` \* | `list`[`input`] | Входные данные/материалы |
| `outputs` \* | `list`[`output`] | Результаты процесса |
| `composed_of` \* | `ref`[] → `operation` | Список операций |
| `control_points` \* | `list`[`control_point`] | Точки контроля (см. секцию 3.2) |
| `mode` \* | `enum` | `Build` \| `Run` |
| `role` \* | `enum` | `Execute` \| `Control` |
| `cycle_time` | `duration` \| "`estimate`" \| "`unknown`" | Типичное время выполнения |
| `capacity` | `number` \| "`estimate`" \| "`unknown`" | Пропускная способность |
| `error_rate` | `percentage` \| "`unknown`" | Доля переделок |
| `systems` | `list[string]` | Используемые информационные системы |
| `process_debt_flag` | `boolean` | Временное решение, ставшее постоянным |
| `delivers` \* | `ref`[] → `H3.deliverable` | Какие результаты производит |
| `requires_support` | `ref`[] → `H5.support_process` | Какие поддерживающие процессы нужны |

#### `operation`

Элементарное действие внутри процесса. Не декомпозируется дальше в рамках H4.

| Поле | Тип | Описание |
|------|------|-------------|
| `inputs` \* | `list`[`input`] | Входы |
| `outputs` \* | `list`[`output`] | Выходы |
| `performer` \* | `string` \| `ref` → `H6.role` \| "TBD" | Кто/что выполняет |
| `duration` | `duration` \| "`estimate`" | Типичная длительность |
| `waiting_states` | `enum`[] | `waiting_customer_input` \| `waiting_external` \| `waiting_internal` |

#### `runtime_binding` — расширение (на `backstage_process`, `support_process` или `operation`)

Мост от графа к работающему софту: какие системы, контракты событий и эндпоинты реализуют этот узел. Здесь граф перестаёт описывать и становится исполняемым. **Самый дрейф-опасный блок справочника** — привязанные системы меняются под вами. Всегда навешивайте `freshness` на узел с `runtime_binding` и относитесь к графу как к *декларации* контракта, а не зеркалу руками собранной системы.

```yaml
runtime_binding:
  system_refs: [crm.hubspot, queue.nats]
  event_schemas: [lead.created.v1, proposal.sent.v2]
  api_endpoints: [POST /proposals]
  module_owner: ref: h7/position_automation_engineer   # ответственность -> H7.position
```

`event_schemas` — контракты на стыках модулей; это ваши контрольные точки, если строите событийную архитектуру.

### Рёбра H4

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `delivers` | `backstage_process` → `H3.deliverable` | Процесс производит результат |
| `requires` | `H3.deliverable` → `backstage_process` | Результат требует процесса |
| `composed_of` | `backstage_process` → `operation` | Процесс состоит из операций |
| `requires_support` | `backstage_process` → `H5.support_process` | Нужен процесс поддержки |
| `depends_on` | `backstage_process` → `backstage_process` | Зависимость внутри H4 |

### Правила валидации H4

1. **Проверка на сирот:** каждый `backstage_process` должен быть достижим от H3 — либо напрямую через `delivers`, либо через другой процесс, который поставляет результат, по `depends_on`. Процесс, производящий упаковку, которая сама не отгружается, но используется процессами, которые отгружают, — не сирота. Недостижим ни от чего на H3 = кандидат на H5 или ликвидацию.
2. **Проверка покрытия:** каждый `H3.deliverable` с `requires` → H4 должен иметь соответствующий процесс.
3. **Каскад SLA:** sum(`operation.duration`) + sum(`control_point.duration`) + буфер 20% ≤ `deliverable`.SLA.
4. **Сигнал общего процесса:** процесс с `delivers` к 3+ результатам = анализ скрытых зависимостей.
5. **Проверка владельца:** каждый `backstage_process` → `owner` заполнен.

---

### Чеклист H4

- [ ] Каждый результат с `requires` → H4 имеет соответствующий процесс
- [ ] Каждый `backstage_process` → ≥1 `delivers` на H3
- [ ] У каждого процесса заполнен владелец
- [ ] Операции разложены, у каждой записана `duration`
- [ ] Каскад SLA проверен: операции + контрольные точки + буфер ≤ SLA результата — размер буфера выбран осознанно (в правилах валидации 20% как отправная точка)
- [ ] Общие процессы (3+ результата) проверены на скрытую связанность
- [ ] Контрольные точки стоят на входах и выходах, а не только в конце
- [ ] Узкое место найдено — вы можете назвать процесс, который ограничивает пропускную способность
- [ ] Для каждого процесса помечено: создание (Build) или эксплуатация (Run)
- [ ] Граница H4 / H5 проведена осознанно, а не досталась по умолчанию

---

## 8. Горизонт 5: Поддерживающие процессы

### Типы узлов

#### `support_process`

Поддерживающий процесс — обслуживает H4, но не создаёт результат, видимый клиенту.

| Поле | Тип | Описание |
|------|------|-------------|
| `process_type` \* | `enum` | `reglament` \| `personal`. `personal` = красный флаг |
| `mode` \* | `enum` | `Run` \| `Build`. Подавляющее большинство — эксплуатация (Run) |
| `cadence` \* | `enum` | `daily` \| `weekly` \| `monthly` \| `quarterly` \| `annual` \| `on_demand` |
| `internal_sla` \* | `sla_object` | Сроки, критерии качества, резервный режим |
| `cost_allocation` \* | `cost_alloc_object` | Тип затрат и сумма |
| `enables` \* | `ref`[] → `H4.backstage_process` \| `H5.support_process` | Что обслуживает. **Пустой список = сирота** |
| `control_points` | `list`[`control_point`] | Точки контроля (см. секцию 3.2) |
| `admission` | `admission_object` | Критерии допуска к процессу (реализация → H6) |

**`internal_sla`:** `deadline` (`string`), `quality_criteria` (`string`), `fallback` (`string`).

**`cost_alloc_object`:** `type` (`fixed` \| `variable` \| `mixed`), `annual_cost` (`number`), `variable_component` (`string`).

**`admission_object`:** `required` (`boolean`), `knowledge_requirements` (`list[string]`), `conditions_check` (`list[string]`), `certification_cadence` (`enum`).

#### `policy`

Формализованное правило, определяющее поведение в процессах.

| Поле | Тип | Описание |
|------|------|-------------|
| `scope` \* | `ref`[] → H4/H5 `process` | Какие процессы регулирует |
| `last_reviewed` \* | `date` | Дата последнего пересмотра |
| `review_cadence` \* | `enum` | Периодичность пересмотра |
| `compliance_type` \* | `enum` | `internal` \| `regulatory` \| `contractual` |

> **Свежесть.** Политики используют универсальный блок `freshness` (§1, Опциональные универсальные блоки). `last_reviewed` / `review_cadence` здесь — частная поверхность того же механизма; держите их синхронными.

#### `compliance_rule`

Внешнее требование (регулятор, закон, стандарт).

| Поле | Тип | Описание |
|------|------|-------------|
| `regulator` \* | `string` | Кто требует |
| `deadline_pattern` \* | `string` | Когда сдавать |
| `penalty_for_violation` \* | `string` | Цена нарушения |
| `enables` \* | `ref`[] → `H5.support_process` | Какой процесс обеспечивает |
| `last_change` \* | `date` | Дата последнего изменения требования |

### Рёбра H5

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `enables` | `support_process` → `H4.backstage_process` | Обслуживает ключевой процесс |
| `enables` | `support_process` → `H5.support_process` | H5 обслуживает другой H5 |
| `governed_by` | `H5.process` → `policy` | Регулируется политикой |
| `complies_with` | `H5.process` → `compliance_rule` | Выполняет требование регулятора |

### Правила валидации H5

1. **Проверка на сирот:** каждый обслуживающий процесс должен стоять на цепочке `enables`, которая заканчивается процессом H4. Обслуживать только другие обслуживающие процессы — нормально: найм обслуживает и ключевые, и обслуживающие. Цепочка, которая никуда не приводит, или процесс вне всякой цепочки — кандидат на ликвидацию. Отчёт, который никто не читает, живёт здесь.
2. **Проверка раздувания:** COUNT(H5) > 2 × COUNT(H4) = сигнал раздувания H5.
3. **Сигнал персонального процесса:** `process_type` = `personal` = риск ключевого человека.
4. **Проверка на зомби:** H5 с `enables`, но `target` не использует результат = зомби.
5. **Каскад SLA:** `H5.internal_sla.deadline` не позднее SLA потребителя.
6. **Покрытие допуском:** если `admission.required` = `true` — `knowledge_requirements` и `certification_cadence` заполнены.

### Чеклист H5

- [ ] Каждый H5 → ≥1 `enables` → H4 или H5, и цепочка заканчивается процессом H4
- [ ] У каждого H5 назначен `owner`
- [ ] `process_type` указан (`personal` → задокументировать риск)
- [ ] `internal_sla` заполнен
- [ ] `cost_allocation` заполнен
- [ ] Для критических процессов заполнен `admission`
- [ ] Политики привязаны к процессам
- [ ] У каждого `compliance_rule` актуальный `last_change`
- [ ] Межгоризонтные проверки пройдены

---

## 9. Горизонт 6: Решения о способе выполнения

### Типы узлов

#### `role`

Набор операций, требующих определённого профиля компетенций.

| Поле | Тип | Описание |
|------|------|-------------|
| `performs` \* | `ref`[] → H4/`H5.operation` | Какие операции выполняет |
| `required_competencies` \* | `ref`[] → `competency` | Необходимые компетенции |
| `labor_type` \* | `enum` | `person_as_process` \| `person_in_process` |
| `work_instructions_ref` | `list[string]` | Ссылки на рабочие инструкции |
| `context_profile` | `context_profile_object` | Профиль для проверки совместимости ролей |

**`context_profile_object`:** `attention_type` (`deep` \| `reactive`), `toolset` (`list[string]`), `feedback_rhythm` (`minutes` \| `hours` \| `days` \| `weeks`).

> **Роль против позиции (глава 9, глава 10, глава 16).** Роль = набор операций + компетенции. Позиция = роль + ответственность (одна позиция, совмещение — только ролей). Должность = позиция, вписанная в H7.

#### `competency`

Конкретный проверяемый навык или знание.

| Поле | Тип | Описание |
|------|------|-------------|
| `level` \* | `enum` | `basic` \| `intermediate` \| `expert` |
| `verification` \* | `string` | Как проверяется (аттестация, тест, демонстрация) |
| `training_path` | `list[string]` | Путь обучения |

#### `sourcing_decision`

Решение свои силы (Make) / купить результат (Buy) / аутсорс (Outsource) / автоматизировать (Automate) для конкретного варианта операции.

| Поле | Тип | Описание |
|------|------|-------------|
| `operation_ref` \* | `ref` → H4/`H5.operation` | Для какой операции |
| `variant` \* | `string` | Описание варианта (сегмент, тариф, география) |
| `decision` \* | `enum` | `make` \| `buy` \| `outsource` \| `automate` |
| `rationale` \* | `string` | Обоснование |
| `labor_type` | `enum` | `person_as_process` \| `person_in_process` (для `make`/`outsource`) |
| `team_type` | `enum` | `division_of_labor` \| `crew` \| `independent_operators` (только для `make`) |
| `roles_required` | `ref`[] → `role` | Какие роли нужны (для `make`) |
| `required_competencies` | `ref`[] → `competency` | Какие компетенции |
| `admission_control` \* | `admission_control_object` | Тип контроля (см. секцию 3.3) |
| `bus_factor` | `integer` | Сколько человек могут выполнить (для `make`) |
| `fallback` \* | `string` | План отката |
| `transition_cost` | `string` | Стоимость перехода |
| `review_trigger` \* | `string` | Условие пересмотра решения |

**`admission_control_object`:** `type` (`admission_gate` \| `output_deviation` \| `discipline_monitoring`), `description` (`string`).

> **`team_type` против `labor_type`.** `labor_type` фиксирует, является ли работа самим человеком (`person_as_process`) или проходит через человека (`person_in_process`). `team_type` фиксирует, как несколько человек внутри одного блока соотносятся между собой, когда `decision` = `make`. Три значения, внутри одного блока никогда не смешиваются: разделение труда (выход одного человека — вход следующего); бригада (универсалы под координатором, любой может взять любую задачу); артель автономных (каждый ведёт свой участок от начала до конца). Полный разбор — в главе 9.

### Рёбра H6

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `performs` | `role` → H4/`H5.operation` | Роль выполняет операцию |
| `requires` | `sourcing_decision` → `competency` | Решение требует компетенции |
| `composes` | `role` → `H7.position` | Роли группируются в позиции |
| `depends_on` | `sourcing_decision` → `sourcing_decision` | Зависимость решений |
| `controls` | `sourcing_decision` → `H5.support_process` | Для `outsource`: контрольный процесс |

> **`controls` не создаёт процесс.** Решение об аутсорсе делает контрольный процесс необходимым, но узел H5 не порождается ребром — он добавляется через процесс изменения графа (гл. 13), как любой другой узел, и только после этого решение на него ссылается. H6 читает с H4 и H5; вверх он ничего не порождает. Если контрольного процесса ещё нет, решение неполно — правило 6 ниже ловит ровно это.

### Правила валидации H6


1. **Покрытие:** каждая операция из H4/H5 → ≥1 `sourcing_decision`. Без = серая зона.
2. **Компетенции для `make`:** если `decision` = `make` → `roles_required` не пуст, у роли — `required_competencies`.
3. **Покрытие вариантов:** если H3 `deliverable` имеет несколько вариантов → каждый → собственный `sourcing_decision`.
4. **Совместимость ролей:** две роли на одной позиции → проверить `attention_type`, `toolset`, `feedback_rhythm`. Время до продуктивности после переключения: минуты = ок, часы = осторожно, дни = несовместимо.
5. **Компетенция-сирота:** `competency` без ссылок из `role` = кандидат на удаление.
6. **Контроль `outsource`:** `decision` = `outsource` → указан механизм контроля (ссылка на H5 или `admission_control`).
7. **Приёмка `buy`:** `decision` = `buy` → зафиксированы критерии оценки результата.
8. **Тип команды для `make`:** если `decision` = `make`, `team_type` задан; если `decision` != `make`, `team_type` можно опустить.

---

### Чеклист H6

- [ ] Каждая операция из H4/H5 → ≥1 решение о способе выполнения — серых зон нет
- [ ] Для каждой записано решение: свои силы / покупка результата / аутсорс / автоматизация
- [ ] Для своих сил: задан `team_type`, `roles_required` не пуст
- [ ] У каждой роли заполнены `required_competencies`
- [ ] У каждой роли заполнен `context_profile`: тип внимания, набор инструментов, ритм обратной связи
- [ ] Совместимость ролей проверена везде, где две роли сходятся на одной должности
- [ ] Для аутсорса: указан механизм контроля (связь с H5 или `admission_control`)
- [ ] Для покупки результата: критерии приёмки задокументированы
- [ ] Допуск (`admission_control`) определён везде, где высока цена ошибки
- [ ] Записан `bus_factor`; операции с единственным носителем знания помечены
- [ ] Для каждого решения заполнены `fallback` (резервный режим) и `review_trigger`
- [ ] По компетенциям-сиротам (на них не ссылается ни одна роль) принято решение

---

## 10. Горизонт 7: Организационная структура

### Типы узлов

#### `organizational_unit`

Структурное подразделение: отдел, команда, группа, департамент.

| Поле | Тип | Описание |
|------|------|-------------|
| `type` \* | `enum` | `department` \| `team` \| `group` \| `division` |
| `parent_unit_ref` | `ref` → `organizational_unit` | Вышестоящая единица (`null` для верхнего уровня) |
| `position_refs` \* | `ref`[] → `position` | Позиции в подразделении |
| `segment_scope` | `ref`[] → `H1.counterparty` | Для каких сегментов; `null` = для всех |
| `mode` | `enum` | `Build` \| `Run` \| `Mixed` |
| `cost_center` | `string` | Привязка к центру затрат |
| `creation_rationale` | `string` | Почему создано (ссылка на зависимости H4–H6) |
| `sunset_condition` | `string` | При каких условиях расформировать |

#### `position`

Должность — группировка ролей из H6.

| Поле | Тип | Описание |
|------|------|-------------|
| `role_refs` \* | `ref`[] → `H6.role` | Роли, составляющие должность |
| `reports_to` \* | `ref` → `position` | Линия подчинения |
| `demands_from` | `ref`[] → `position` | Позиции, от которых требует результат |
| `authority_scope` \* | `text` | Что вправе требовать — конкретные результаты |
| `accountability_level` | `enum` | `strategy` \| `goals_budgets` \| `tasks_plans` \| `execution` — уровень ответственности, который требует кресло (глава 10, глава 16) |
| `min_orientation` | `enum` | `transactional` \| `contributive` — минимально допустимая ориентация на вклад; `extractive` недопустим для кресла с автономией или доступом к рычагам (глава 16) |
| `unit_ref` \* | `ref` → `organizational_unit` | Подразделение |
| `current_holder` | `string` | Кто сейчас занимает |
| `headcount` | `integer` | Количество людей |
| `substitution_plan` | `string` | Кто замещает при отсутствии |
| `decision_rights` | `list[string]` | Решения без эскалации |
| `escalation_path` | `string` | Куда эскалируется |

> **`accountability_level`** соответствует лестнице кресел из главы 16 (`execution` → `tasks_plans` → `goals_budgets` → `strategy`). Два случая лежат вне её: *присутствие* (ниже execution — кандидат предъявляет регалии вместо продукта; это не наёмное кресло) и *владение* (выше strategy — партнёр/доля, не позиция на зарплате). Охват и ориентация кандидата сопоставляются с креслом при найме; они не объекты графа, потому что граф моделирует компанию, а не соискателей.

#### `promise_policy` — расширение (на `position`)

Полномочие на внешние обязательства: что эта позиция вправе пообещать клиенту и когда обязана эскалировать. Отличается от `authority_scope` выше, который смотрит *внутрь* (что позиция вправе требовать внутри). Две оси: требование (внутрь) против обещания (наружу).

```yaml
promise_policy:
  can_promise: true
  max_discount: "10%"
  max_sla: "48h"
  requires_approval_if:
    - "кастомная интеграция"
    - "юридическое обязательство"
    - "цена ниже пола"
```

Конкретные лимиты (скидка %, SLA) — иллюстративные; держите их в отраслевых примерах (Приложение F), а не в общей схеме.

#### `reporting_line`

Формальная линия подчинения.

| Поле | Тип | Описание |
|------|------|-------------|
| `from_position` \* | `ref` → `position` | Подчинённая |
| `to_position` \* | `ref` → `position` | Вышестоящая |
| `right_type` \* | `enum` | `formal` \| `functional` \| `dotted` |
| `right_source` \* | `string` | На чём основано право |
| `scope` | `enum` | `full` \| `project` \| `temporary` |
| `valid_until` | `date` | Для временных |
| `legitimacy_check` | `object` | Подтверждено ли реальным правом (`boolean` + `comment`) |

#### `dependency_line`

Линия зависимости — кто от кого зависит для получения результата.

| Поле | Тип | Описание |
|------|------|-------------|
| `from_position` \* | `ref` → `position` | Кому нужен результат |
| `to_position` \* | `ref` → `position` | Кто поставляет результат |
| `process_ref` \* | `ref` → H4/`H5.process` | Какой процесс порождает зависимость |
| `frequency` \* | `enum` | `daily` \| `weekly` \| `per_event` \| `on_demand` |
| `criticality` \* | `enum` | `low` \| `medium` \| `high` \| `blocking` |
| `sla_ref` | `ref` → sla | Внутренний SLA |
| `escalation_mechanism` | `string` | Как эскалируется |
| `formalization_status` | `enum` | `informal` \| `agreed` \| `contracted` |
| `cost_of_failure` | `string` | Что происходит при сбое |

### Рёбра H7

| Тип связи | От → К | Описание |
|-----------|--------|----------|
| `composes` | `H6.role` → `position` | Роли собираются в позицию |
| `reports_to` | `position` → `position` | Линия подчинения |
| `depends_on` | `position` → `position` | Линия зависимости (из конкретного процесса) |
| `segment_scope` | `organizational_unit` → `H1.counterparty` | Привязка к клиентскому сегменту |

### Правила валидации H7

1. **Позиция без ролей:** `position` без `role_refs` = не выполняет операций. Кандидат на ликвидацию.
2. **Оторванное подразделение:** `organizational_unit`, у позиций которого нет `dependency_line` к/от других подразделений И нет `role_refs` к H4 = оторвано от графа.
3. **Подчинение без зависимости:** A подчиняется B, но ни одна операция A не зависит от B и наоборот → зачем подчинение?
4. **Диапазон зависимостей:** входящих `dependency_line` с `criticality` = `high`/`blocking` > 10 на одну позицию = перегрузка.
5. **Право без возможности:** `reporting_line` с `right_type` = `formal`, но `authority_scope` пуст = подчинение без инструментов контроля.
6. **Неформальная критическая зависимость:** `dependency_line` с `criticality` = `high` + `formalization_status` = `informal` = критичная зависимость на личных договорённостях.
7. **Разрыв между подчинением и зависимостью:** > 50% `critical` `dependency_lines` идут вне `reporting_line` цепочки = расхождение формальной и реальной структуры.

---

### Чеклист H7

- [ ] У каждой должности → ≥1 `role_refs` — должностей, которые ничего не исполняют, нет
- [ ] В каждом контуре принятия решения ответственность лежит ровно на одном человеке
- [ ] По каждой должности проверены три условия: понимаю / решаю / отвечаю
- [ ] Каждое организационное подразделение связано с графом через `role_refs` или `dependency_lines`
- [ ] За каждой линией подчинения стоит реальная операционная зависимость
- [ ] `authority_scope` заполнен везде, где `right_type` = `formal`
- [ ] По критическим неформальным зависимостям принято решение о формализации
- [ ] Входящие критические зависимости на должность сопоставлены с порогом, который вы задали сами (в правилах валидации 10 как отправная точка)
- [ ] Формальная и фактическая структуры сопоставлены: доля критических зависимостей вне цепочки подчинения посчитана и признана приемлемой (в правилах валидации 50% как отправная точка)
- [ ] Тип команды в подразделении соответствует работе, которая там реально делается

---

## 11. Каноническая таблица рёбер

Именованные типы рёбер — те, по которым вы ходите, когда читаете граф или применяете правило валидации. Каждое определено один раз, в одном направлении. Атрибуты-ссылки на узлах (раздел 2) тоже связывают узлы, но здесь не перечислены.

### Внутри горизонтов

| `edge_type` | От → К | Описание |
|-----------|--------|----------|
| `experiences` | `counterparty` → `pain_point` | Контрагент переживает боль (H1) |
| `activates` | `trigger` → `step` | Триггер запускает шаг (H1) |
| `escalates` | `trigger` → `pain_point` | Триггер усиливает боль (H1) |
| `leads_to` | `step` → `step`, `touchpoint` → `touchpoint` | Переход вперёд (H1, H2) |
| `returns_to` | `step` → `step` | Возврат назад (H1) |
| `considers` | `step` → `alternative` | Рассмотрение альтернативы (H1) |
| `filters` | `evaluation_criterion` → `alternative` | Отсечение по критерию (H1) |
| `enters_via` | `entry_point` → `step` | Боковой вход (H1) |
| `loops_to` | `step`(5) → `step`(1) | Петля возврата (H1) |
| `contains` | `channel` → `touchpoint` | Канал содержит точку контакта (H2) |
| `competes_with` | `touchpoint` → `touchpoint` | Конкуренция (H2) |
| `redirects_to` | `touchpoint` → `H1.alternative` | Перенаправление (H2) |
| `recovers` | `deliverable` → `deliverable` | Восстановление после сбоя (H3) |
| `variant_of` | `deliverable_variant` → `deliverable` | Вариант (H3) |
| `composed_of` | `backstage_process` → `operation` | Состоит из (H4) |
| `governed_by` | `process` → `policy` | Регулируется (H5) |
| `complies_with` | `process` → `compliance_rule` | Соответствует требованию (H5) |
| `depends_on` | `node` → `node`, один горизонт | Выход одного узла питает другой на том же горизонте. Допустимо на любом горизонте — так выражаются промежуточные результаты: результат, потребляемый другим результатом; процесс, производящий упаковку для других процессов |
| `reports_to` | `position` → `position` | Подчинение (H7) |

### Между горизонтами

| `edge_type` | От → К | Описание |
|-----------|--------|----------|
| `generates` | H1 → H2 | `question_node` порождает точку контакта |
| `generates` | H2 → H3 | точка контакта порождает результат |
| `requires` | H3 → H4 | Результат требует процесса |
| `delivers` | H4 → H3 | Процесс производит результат |
| `requires_support` | H4 → H5 | Ключевой процесс нуждается в обслуживающем |
| `enables` | H5 → H4, H5 → H5 | Обслуживающий процесс обслуживает ключевой (или другой обслуживающий) |
| `performs` | `H6.role` → H4/`H5.operation` | Роль выполняет операцию |
| `composes` | `H6.role` → `H7.position` | Роли собираются в позицию |
| `controls` | `H6.sourcing_decision` → H5 | Контрольный процесс для `outsource` |
| `segment_scope` | `H7.unit` → `H1.counterparty` | Привязка к сегменту |
| `sourced_by` | H4/`H5.operation` → `H6.sourcing_decision` | Здесь решается, каким способом выполняется эта операция (обратный вид — `operation_ref` на решении) |
> **Обратная пара `requires` ↔ `delivers`:** Это одно и то же ребро, видимое с двух сторон. В графе хранится один раз. `requires` — представление со стороны H3 («мне нужен процесс»). `delivers` — представление со стороны H4 («я произвожу результат»). В софте — одно ребро с направлением.

---

## 12. Кросс-горизонтные правила валидации (сводные)

### Сквозная прослеживаемость

```
FOR EACH counterparty IN H1:
  trace = counterparty → pain_points → triggers → steps → question_nodes 
          → touchpoints(H2) → deliverables(H3) → processes(H4) 
          → support(H5) → sourcing(H6) → positions(H7)
  IF any link in trace is broken:
    FLAG "Разорванная трасса для контрагента {counterparty.name} на {broken_link}"
```

### Каскад покрытия (сверху вниз)

| Проверка | Правило | Уровень |
|----------|---------|---------|
| H1→H2 | Каждый `question_node` → ≥1 `touchpoint` | Критично |
| H2→H3 | Каждый `owned` `touchpoint` с `generates` → `deliverable` существует | Критично |
| H3→H4 | Каждый `deliverable` → ≥1 `process` (или `self_service`) | Критично |
| H4→H5 | H4 с `requires_support` → H5 существует | Предупреждение |
| H4/H5→H6 | Каждая `operation` → ≥1 `sourced_by` → `sourcing_decision` | Предупреждение |
| H6→H7 | Каждая `role` (`make`) → ≥1 `position` | Предупреждение |

### Каскад SLA (сверху вниз)

```
FOR EACH deliverable IN H3:
  expected = deliverable.sla.target
  actual = SUM(processes.cycle_time) + SUM(control_points.duration) + buffer(20%)
  IF actual > expected:
    FLAG "Нарушение SLA: {deliverable.name} обещает {expected}, процессам нужно {actual}"
```

### Проверки на сирот (снизу вверх)

| Горизонт | Правило | Действие |
|----------|---------|----------|
| H2 | `touchpoint` без `info_need_ref` на H1 | Ликвидировать — он отвечает на вопрос, который никто не задаёт |
| H3 | `deliverable` недостижим от H2 по `triggered_by`, напрямую или через `depends_on` | Ликвидировать или оставить как объявленный промежуточный результат |
| H4 | `process` недостижим от H3 по `delivers`, напрямую или через `depends_on` | Переместить в H5 или ликвидировать |
| H5 | обслуживающий процесс, чья цепочка `enables` не заканчивается процессом H4 | Ликвидировать |
| H6 | `competency` без ссылок из `role` | Удалить |
| H7 | `position` без `role_refs` | Ликвидировать |
| H7 | `unit` без `dependency_lines` к другим `unit` | Проверить на отрыв |

### Проверки согласованности

| Проверка | Правило |
|----------|---------|
| Формат владельца | `maturity` ≥ 3 → `owner` = `ref`, не `string` |
| Свежесть | узел за `freshness.expires_at` → применить `stale_action` (`warn` / `block` / `require_owner_review`) |
| Терминология | `delivers` → `H3.deliverable` (не `service`, не `process`) |

---

## 13. Шаблоны ИИ-промптов

Готовые промпты для заполнения и валидации графа через ИИ.

### Промпт 1: заполнение узла H4

```
У меня есть deliverable на H3:
- name: [название]
- SLA: [целевое время]
- acceptance_criteria: [критерии]

Опиши backstage_process для производства этого deliverable в формате DSL:
- inputs (включая customer_inputs)
- outputs
- operations (список элементарных действий)
- control_points (с check_type: process_design или execution_discipline)
- cycle_time (оценка)
- mode (Build или Run)
- role (Execute или Control)

Формат: YAML. Не придумывай данные — где не знаешь, пиши "unknown" или "estimate".
```

### Промпт 2: аудит сирот и раздувания

```
Вот список узлов H5 и H4 (core processes) моей компании:

H4: [список]
H5: [список]

Проведи три проверки:
1. Orphan check: какие H5 не имеют связи enables → H4?
2. Bloat check: соотношение H5/H4 (норма: ≤ 2:1)
3. Zombie check: какие H5 перечислены как enables, но H4-потребитель не использует их результат?

Для каждого найденного — рекомендация: ликвидировать, объединить, или пересмотреть связь.
```

### Промпт 3: проверка каскада SLA

```
Вот deliverable с H3 и процесс, который его производит:

Deliverable: [YAML]
Process: [YAML с operations и control_points]

Проверь:
1. SUM(operation.duration) + SUM(control_point.duration) + 20% buffer ≤ deliverable.sla.target?
2. Если нет — какие операции являются bottleneck?
3. Предложи варианты: (a) упростить процесс, (b) пересмотреть SLA, (c) автоматизировать bottleneck.
```

### Промпт 4: решение о способе выполнения H6

```
У меня есть операция из H4:
- name: [название]
- inputs: [входы]
- outputs: [выходы]
- duration: [длительность]
- текущий исполнитель: [кто делает сейчас]

Помоги сформулировать sourcing_decision в формате DSL:
- decision: make / buy / outsource / automate (с обоснованием)
- Для каждого варианта: pros, cons, bus_factor, fallback, review_trigger
- Критерии выбора: частота, вариативность, цена ошибки, скорость, доступность на рынке

Формат: YAML. Где нужна информация, которой у тебя нет — задай вопрос.
```

### Промпт 5: проверка совместимости ролей H7

```
Я хочу совместить две роли на одной позиции:

Роль 1: [YAML с context_profile]
Роль 2: [YAML с context_profile]

Проверь совместимость по трём критериям:
1. attention_type: обе deep из разных областей? → несовместимы
2. toolset: работа в разных средах, разный словарь? → маркер
3. feedback_rhythm: одна «быстрая» (минуты), другая «медленная» (недели)? → рискованно

Практический тест: время до продуктивности после переключения.
Минуты — ок. Часы — осторожно. Дни — несовместимо.

Дай вердикт и обоснование.
```

---

## 14. Пример YAML: SaaS-компания (ПО как услуга), сквозной фрагмент H1→H4

```yaml
# === H1 ===
counterparty:
  id: p_ops_manager
  name: "Операционный директор, B2B SaaS, 50-200 сотрудников"
  horizon: H1
  node_type: counterparty
  role: "Руководитель операционного отдела"
  context: "Быстро растущий SaaS, 80 сотрудников, процессы в головах"
  confidence: 0.8
  evidence: ["12 интервью", "анализ поддержки: 40% тикетов — про процессы"]
  pain_refs: [pp_tribal_knowledge]

pain_point:
  id: pp_tribal_knowledge
  name: "Знания в головах, не в системе"
  horizon: H1
  node_type: pain_point
  severity: high
  frequency: constant
  cost_estimate: "2-3 недели онбординг нового менеджера вместо 3 дней"
  awareness: aware_active
  trigger_refs: [tr_key_person_quit]
  confidence: 0.85
  evidence: ["выходные интервью", "опросы после онбординга"]

trigger:
  id: tr_key_person_quit
  name: "Ключевой сотрудник увольняется"
  horizon: H1
  node_type: trigger
  event: "Тимлид подал заявление, команда из 8 человек осталась без носителя контекста"
  source: internal
  urgency: high
  activates: [step_2]

# === H2 ===
touchpoint:
  id: tp_process_audit_landing
  name: "Лендинг: 'Сколько стоит хаос в процессах?'"
  horizon: H2
  node_type: touchpoint
  ownership_type: owned
  step_ref: step_2
  info_need_ref: [qn_cost_of_chaos]
  counterparty_ref: [p_ops_manager]
  channel_ref: ch_website
  moment_of_truth: true
  customer_expectation: "Понять масштаб проблемы в деньгах"
  content_type: self_serve_tool
  friction_level: low
  latency: "мгновенно"
  outcome: "Калькулятор показал: хаос стоит $180K/год. Запрос демо."
  outcome_type: progress
  confidence: 0.7
  evidence: ["GA: 200 визитов/мес", "конверсия в демо: 8%"]

# === H3 ===
deliverable:
  id: del_chaos_calculator
  name: "Калькулятор стоимости процессного хаоса"
  horizon: H3
  node_type: deliverable
  outcome_type: education
  triggered_by: [tp_process_audit_landing]
  customer_inputs:
    - input_name: "Количество сотрудников"
      format: "число"
    - input_name: "Средняя зарплата"
      format: "число"
    - input_name: "Сколько ключевых людей ушло за год"
      format: "число"
  sla:
    target: "мгновенно"
    inherited_from: tp_process_audit_landing
    clock_starts: on_trigger
    conflict: none
  acceptance_criteria:
    - "Формула расчёта корректна"
    - "Результат правдоподобен (не пугает и не занижает)"
  qualification_signals:
    - "Пользователь запрашивает демо после расчёта"
  requires: [bp_calculator_maintenance]
  scalability_class: fixed

# === H4 ===
backstage_process:
  id: bp_calculator_maintenance
  name: "Поддержка калькулятора стоимости хаоса"
  horizon: H4
  node_type: backstage_process
  purpose: "Обеспечить актуальность формул и бенчмарков в калькуляторе"
  mode: Run
  role: Execute
  triggered_by: [del_chaos_calculator]
  inputs:
    - "Отраслевые бенчмарки (ежеквартально)"
    - "Обратная связь от пользователей"
  outputs:
    - "Обновлённые формулы"
    - "Актуальные коэффициенты"
  composed_of:
    - op_collect_benchmarks
    - op_update_formulas
    - op_regression_test
  control_points:
    - id: cp_formula_accuracy
      check_type: process_design
      criteria: "Результат калькулятора отклоняется от ручного расчёта не более чем на 15%"
      checker: "Менеджер продукта"
      frequency: quarterly
  cycle_time: "2 дня/квартал"
  owner: "Менеджер продукта"
  delivers: [del_chaos_calculator]
```

---

*Полная спецификация. Для отраслевых примеров — см. Приложение F.*
