# Decision 006 — Immutable Engine Contract

## Статус

**Accepted**

---

# Дата принятия

Принято во время реализации **Build №006 — `common/models.py`**.

---

# Контекст

Во время проектирования единого контракта аналитических движков возник вопрос:

> **Могут ли модели результата изменяться после завершения расчёта?**

Рассматривались два варианта.

---

# Вариант 1

Изменяемые (`mutable`) модели.

После создания объекта любой компонент платформы может изменить его поля.

Например:

```python
result.score = ...
result.reason = ...
result.direction = ...
```

### Преимущества

- проще писать код;
- меньше ограничений.

### Недостатки

- невозможно гарантировать целостность результата;
- результат может измениться после публикации;
- журнал может содержать значения, отличающиеся от реально использованных;
- сложнее искать ошибки;
- возрастает риск скрытых побочных эффектов.

---

# Вариант 2

Неизменяемые (`immutable`) модели.

После создания объекта изменение его полей невозможно.

При необходимости формируется новый объект результата.

### Преимущества

- результат всегда остаётся неизменным;
- журнал отражает фактическое состояние расчёта;
- безопасная передача между компонентами;
- отсутствуют скрытые изменения;
- упрощается диагностика;
- упрощается тестирование;
- повышается предсказуемость поведения платформы.

### Недостатки

- при изменении необходимо создавать новый экземпляр объекта.

---

# Принятое решение

Для всех моделей, описывающих результат работы аналитических движков, используется **неизменяемый контракт**.

Все основные модели объявляются как:

```python
@dataclass(frozen=True, slots=True)
```

---

# Область применения

Правило распространяется на:

- `EngineResult`;
- `EngineContext`;
- `EngineMetric`;
- `EngineDiagnostics`;
- `EngineEvaluationMeta`;
- `EngineDependencyResult`;

а также на все будущие модели, описывающие результаты работы Engine.

---

# Исключения

Настоящее правило **не распространяется** на:

- Runtime State;
- AutoTrade State;
- Position State;
- Execution Runtime;
- внутренние рабочие объекты расчёта.

Эти объекты отражают изменяющееся состояние платформы и по своей природе являются изменяемыми.

---

# Причины принятия решения

Использование неизменяемых моделей обеспечивает:

- целостность результатов анализа;
- безопасную передачу данных между Engine;
- корректное журналирование;
- предсказуемость поведения системы;
- отсутствие скрытых побочных эффектов;
- упрощение сопровождения проекта в долгосрочной перспективе.

---

# Архитектурные последствия

После принятия настоящего решения:

- результаты Engine не изменяются после создания;
- каждый новый расчёт формирует новый объект результата;
- публикация событий всегда выполняется на основе завершённого результата;
- журнал содержит фактически опубликованные данные;
- Coordinator работает только с завершёнными результатами анализа.

---

# Связанные документы

- `runtime_contract.md`
- `architecture_principles.md`
- `development_process.md`
- `builds/build-006-common-models.md`

---

# История

| Версия | Изменение |
|---------|-----------|
| 1.0 | Первое принятие архитектурного решения. |