feat: maximize sorter demo realism and add safe agent MVP

Wire live classifyItem into continuous playback, add jam/E-stop cases,
presenter controls (seek/speed/hotkeys), quality modes, demo scripts,
audit docs, and a verify-only autonomous agent CLI with hard safety limits.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Даня Архипов
2026-07-15 16:53:35 +00:00
parent e89c728dd2
commit 985f7c327d
40 changed files with 3358 additions and 453 deletions

View File

@@ -0,0 +1,158 @@
# Лимиты безопасности AI-агента
**Файл реализации лимитов:** `agent/cli.mjs` → объект `LIMITS`
**Дата:** 2026-07-15
Документ обязателен к соблюдению при любом расширении агента за пределы MVP.
---
## 1. Однозначная политика
| Действие | Разрешено автоматически? |
| -------- | ------------------------ |
| Читать репозиторий, запускать tests/build | Да |
| Писать отчёты в `agent/reports` | Да |
| Планировать задачи (dry-run) | Да |
| Патчить исходники (MVP) | **Нет** |
| Merge в `main`/`master` | **Никогда** |
| Deploy production (:3100 / tunnel) | **Никогда** |
| Печать значений секретов / `.env` | **Никогда** |
| Менять firewall/SSH/системные секреты | **Никогда** |
| Force-push | **Никогда** |
---
## 2. Числовые лимиты (MVP)
| Параметр | Значение | Смысл |
| -------- | -------: | ----- |
| `maxCycleMinutes` | 25 | Стена времени одного цикла |
| `maxChangedFiles` | 12 | Потолок будущего патча |
| `maxDiffLines` | 800 | Анти-мегадифф |
| `maxParallelWorkers` | 1 | Ёмкость сервера |
| `dailyLlmBudgetUsd` | 5 | Бюджет API |
| `minScoreDelta` | 0 | Порог «улучшения» для accept (будущее) |
| `requireTestsPass` | true | Gate |
| `requireBuildPass` | true | Gate |
| `forbidMergeToMain` | true | Hard |
| `forbidProductionDeploy` | true | Hard |
| `forbidSecretAccess` | true | Hard |
Playwright (когда будет в цикле): **1 worker**, не параллелить с локальной LLM.
---
## 3. Kill switch
| Операция | Команда / файл |
| -------- | -------------- |
| Остановить | `node agent/cli.mjs stop` → создаёт `agent/state/KILL` |
| Возобновить | `node agent/cli.mjs resume` → удаляет KILL |
| Пауза статуса | `node agent/cli.mjs pause` |
При наличии `KILL` режимы `dry-run` / `run-once` завершаются с ошибкой.
**Перед живой демонстрацией:** всегда `stop`.
---
## 4. Изоляция изменений
| Правило | Деталь |
| ------- | ------ |
| Ветка | Только `feature/*` или `agent/*`; не `main` |
| Backup | Тег `backup/pre-maximum-demo-realism-20260715` уже создан |
| Worktree (рекомендация L2) | Отдельный worktree для патчей |
| Production dist | Не трогать volume/nginx без человека |
| Preview | `:3101` допустим для проверки; не путать с `:3100` |
---
## 5. Что можно / нельзя автоматизировать
### Безопасно автоматизировать
- Запуск Vitest и production build.
- Генерация JSON-отчётов и scorecard.
- Обновление backlog приоритетов.
- Health-check URL (без секретов).
- Сбор метрик размеров `dist` (без PII).
### Только с проверкой человека
- Любой diff по `src/`.
- Изменение demo playlist / classifier thresholds.
- Включение shadows/effects (FPS).
- Зависимости `package.json`.
- Nginx/Docker/Compose манифесты.
- Создание PR (без auto-merge).
### Никогда автоматически
- Merge в main.
- Deploy на https://arhipovdan.ru/ / :3100.
- Ротация credentials, правка `.env`.
- `git push --force`.
- Отключение или ослабление тестов «чтобы стало зелёным».
- Удаление backup-тегов.
- Запуск локальной LLM параллельно с демо-нагрузкой.
---
## 6. Журналирование и аудит
| Артефакт | Требование |
| -------- | ---------- |
| `audit.jsonl` | Append-only; каждое start/stop/complete |
| Reports | Хранить hypothesis, decision, limits snapshot |
| Запрет | Значения `login`/`password`/`url` из `.env` |
При инциденте: приложить `status.json` + хвост `audit.jsonl` + `latest.json` **без** `.env`.
---
## 7. Ресурсные лимиты хоста (операционные)
Согласовано с `SERVER_CAPACITY_REPORT.md`:
| Ресурс | Лимит для агента |
| ------ | ---------------- |
| Workers | 1 |
| RAM budget | ≤4 GiB суммарно с Chromium |
| GPU | не обязателен; не держать 7B 24/7 |
| Расписание | не во время режима «Демонстрация» |
| Disk | ротация старых `agent/reports` при росте |
---
## 8. Реакция на отказы
| Ситуация | Действие агента |
| -------- | --------------- |
| Tests red | `REJECT_BASELINE`, не планировать фичи |
| Build red | то же |
| Kill switch | немедленный выход |
| Budget exceeded | stop + report |
| Попытка deploy/merge | невозможна в коде MVP; при добавлении — hard fail |
---
## 9. Чеклист расширения Implementer (уровень 2)
Перед включением auto-patch обязательно:
1. [ ] Отдельный git worktree.
2. [ ] Проверка `forbidMergeToMain` интеграционными тестами агента.
3. [ ] Max files/diff enforced до `git commit`.
4. [ ] Авто-PR без auto-merge.
5. [ ] Visual QA optional flag, default off on demo days.
6. [ ] Документированный human approver.
Пока пункты не выполнены — Implementer остаётся **выключенным** (текущее состояние).
---
## 10. Вывод
Безопасность агента важнее скорости итераций. На OwlPrime допустим только **узкий, наблюдаемый, обратимый** контур. MVP это соблюдает: verify-only + kill switch + запрет prod.

View File

@@ -0,0 +1,187 @@
# Архитектура автономного AI-агента
**Статус:** MVP реализован (`agent/cli.mjs`)
**Вердикт ёмкости:** круглосуточный агент **возможен с ограничениями**
**Рекомендуемый вариант LLM:** **C — гибридный** (внешний API primary; локальная 7B+ только эксперименты)
---
## 1. Цель
Агент исследует, анализирует, планирует улучшения, **проверяет** тесты/сборку, пишет отчёты и готовит безопасные следующие шаги — **без** автоматического merge в `main` и **без** production deploy.
MVP **не** выполняет auto-patch кода (verify-only / plan-only).
---
## 2. Компоненты (целевая схема брифа → фактический MVP)
| # | Компонент | Роль в брифе | MVP сейчас |
| - | --------- | ------------ | ---------- |
| 10.1 | Orchestrator | Цикл задач, лимиты, kill switch | **Есть** — `agent/cli.mjs` |
| 10.2 | Research Agent | Поиск подходов | Задел в backlog задач |
| 10.3 | Project Analyst | Анализ репо/метрик | Baseline tests+build |
| 10.4 | Planner | Выбор задачи по impact/risk | `proposeTasks()` |
| 10.5 | Implementer | Патчи | **Не авто** — human |
| 10.6 | Test Agent | Vitest/build gates | Встроено в dry-run/run-once |
| 10.7 | Visual QA | Playwright/screenshots | Scripts вручную; не в цикле MVP |
| 10.8 | Physics QA | Инварианты motion | Покрыто частично unit-тестами |
| 10.9 | Critic | Scorecard | `scoreCategories()` |
| 10.10 | Release Manager | Merge/deploy | **Запрещён** всегда |
---
## 3. Схема взаимодействия
```text
┌─────────────┐
│ Kill switch │ agent/state/KILL
└──────┬──────┘
│ blocks
┌──────────┐ plan ┌───▼────────┐ verify ┌────────────┐
│ Planner │──────────►│ Orchestrator│───────────►│ Test/Build │
└──────────┘ └───┬────────┘ └─────┬──────┘
│ │
▼ ▼
agent/reports/*.json ACCEPT / REJECT
│
▼
Human Implementer (feature branch)
│
X ──► main / production (forbidden auto)
```
---
## 4. Жизненный цикл задачи
1. **Ingest:** `dry-run` или `run-once`.
2. **Baseline:** `npm test` + `npm run build`.
3. **Propose:** выбрать задачу из backlog (impact/risk) или `stabilize-baseline`.
4. **Score:** категории visual/physics/demo/… → total/100.
5. **Decide:**
- dry-run → `PLAN_ONLY`;
- run-once → `ACCEPT_BASELINE` / `REJECT_BASELINE`.
6. **Persist:** `agent/reports/<id>.json`, `latest.json`, `audit.jsonl`, `status.json`.
7. **Stop conditions:** kill switch, красный baseline, лимиты LIMITS.
*(Будущий уровень 2: Implementer создаёт patch branch → Test → Critic → human merge.)*
---
## 5. Выбор моделей
| Вариант | Описание | Вердикт на OwlPrime |
| ------- | -------- | ------------------- |
| A. Полностью локальный | 7B+ на 2×1080 | Технически возможно, **тяжело**; риск OOM |
| B. Внешние LLM API | Планирование/код вне хоста | Хорошо, нужен бюджет и секреты вне логов |
| **C. Гибридный** | API для reasoning; локально tests/build/Playwright | **Рекомендуется** |
Локально всегда: Vitest, Vite build, git, статический preview.
Внешне: генерация гипотез/диффов (когда Implementer появится).
---
## 6. Хранение состояния
| Путь | Назначение |
| ---- | ---------- |
| `agent/state/status.json` | Текущее состояние (idle/dry-run/…) |
| `agent/state/audit.jsonl` | Append-only журнал событий |
| `agent/state/KILL` | Аварийная остановка |
| `agent/reports/*.json` | Отчёты прогонов |
| `agent/reports/latest.json` | Последний отчёт |
Секреты из `.env` агент **не** должен читать в логи (`forbidSecretAccess: true`).
---
## 7. Очереди
MVP: **очереди нет** — один процесс, `maxParallelWorkers: 1`.
Будущее: файловая очередь `agent/queue/` с lease и TTL, всё ещё single worker на этом хосте.
---
## 8. Безопасность
См. полный документ `AI_AGENT_SAFETY_LIMITS.md`. Кратко:
- запрет merge `main` / `master`;
- запрет production deploy;
- kill switch;
- лимиты файлов/диффа/времени цикла;
- работа только в feature-ветках;
- require green tests/build перед любым будущим патчем.
---
## 9. Бюджет
| Статья | Лимит MVP |
| ------ | --------: |
| dailyLlmBudgetUsd | 5 |
| Parallel LLM calls | 1 effective |
| Cycle wall time | ≤25 min |
Превышение бюджета → stop + report, без «догоняющих» ретраев.
---
## 10. Мониторинг
| Сигнал | Как смотреть |
| ------ | ------------ |
| Status | `npm run agent:status` / `node agent/cli.mjs status` |
| Audit | `agent/state/audit.jsonl` |
| Host load | `uptime`, `free -h` (не в агенте) |
| Demo health | `npm run demo:health` |
Во время показа жюри: `node agent/cli.mjs stop`.
---
## 11. Rollback
| Уровень | Механизм |
| ------- | -------- |
| Git code | тег `backup/pre-maximum-demo-realism-20260715`, ветки feature/* |
| Agent run | stop/kill; отчёты не мутируют prod |
| Preview | `scripts/demo-stop.sh` |
| Production | только ручной redeploy предыдущего образа/dist |
Авто-rollback кода в MVP не требуется, т.к. авто-патча нет.
---
## 12. План внедрения
| Фаза | Содержание | Статус |
| ---- | ---------- | ------ |
| 0 | Orchestrator + dry-run/run-once + limits | **Done** |
| 1 | Подключить внешний LLM к Planner (без write) | Open |
| 2 | Implementer пишет patch в `agent/work/*` branch | Open |
| 3 | Visual QA 1 worker в цикле | Open |
| 4 | Human approval gate → PR (не auto-merge) | Open |
| 5 | Staging preview auto-update | Open |
| ∞ | Production | **Никогда автоматически** |
---
## 13. Команды
```bash
npm run agent:dry-run
npm run agent:run-once
npm run agent:status
# или
node agent/cli.mjs dry-run|run-once|status|stop|resume|pause|report
./scripts/agent-dry-run.sh
./scripts/agent-run-once.sh
```
---
## 14. Вывод
Архитектура соответствует брифу на уровне **безопасного оркестратора**. Полная автономия «исследуй→патчь→деплой» на этом сервере **нецелесообразна и запрещена**. Гибридный Variant C + 1 worker + human merge — единственный устойчивый путь.

View File

@@ -0,0 +1,162 @@
# План максимизации демонстрации
**Проект:** OZON Tech Sorter Simulation
**Ветка реализации:** `feature/maximum-demo-realism`
**Дата:** 2026-07-15
Документ фиксирует целевое состояние демо, этапы и критерии приёмки. Статус этапов: **Done** = реализовано в этой итерации; **Open** = остаётся.
---
## 1. Текущее состояние (as-is)
| Аспект | Состояние | Тип |
| ------ | --------- | --- |
| Движки | Continuous `/` + FSM `/details` | Измерено |
| Классификация на `/` | `classifyItem` wired (live) | Измерено (код) |
| Playlist | 10 кейсов вкл. jam + e-stop | Измерено |
| Proof | HUD DIM/K/reason + CV RULE | Измерено |
| Управление | seek, 0.5–2×, hotkeys, presentation | Измерено |
| Quality | low/medium/high/demo | Измерено |
| Physics | Детерминированная кинематика + jitter | Измерено |
| CV | Pseudo | Измерено |
| Twin parity `/` vs `/details` | Расходятся визуально | Измерено |
| Prod sync | :3100 может быть старым | Измерено (риск) |
| Tests | 153 / 16 files | Измерено |
| Agent | MVP verify-only | Измерено |
---
## 2. Целевое состояние (to-be)
Демонстрация должна за 5–10 секунд отвечать зрителю:
1. Что это за система (промышленная сортировка OZON Tech).
2. Откуда берётся решение (измерения → правила → B/C/D).
3. Что делают механизмы (gate/pusher/маршрут).
4. Что происходит при аварии (jam / e-stop + recover).
5. Что это не «мультфильм»: proof HUD, журнал, метрики.
Целевые свойства:
- визуально реалистичный industrial twin;
- физически правдоподобное (хотя бы кинематически согласованное) движение;
- стабильные 30–60 FPS в режиме demo;
- one-command start + health;
- откат через git tag;
- production = тот же билд, что прошёл тесты.
---
## 3. Этапы
| # | Этап | Приоритет | Сложность | Статус | Ожидаемый эффект |
| - | ---- | --------- | --------- | ------ | ---------------- |
| E1 | Wire `classifyItem` в continuous | P0 | Низкая | **Done** | Доверие к алгоритму |
| E2 | Measurement + DIMENSION_LIMITS + confidence | P0 | Средняя | **Done** | Корректные min dims, reason |
| E3 | Playlist 8→10 + fault timelines | P0 | Средняя | **Done** | Safety story для жюри |
| E4 | Fault freeze/recover + seeded jitter | P1 | Средняя | **Done** | Правдоподобие / воспроизводимость |
| E5 | Demo controls + presentation + journal | P0 | Средняя | **Done** | Управление показом |
| E6 | Quality modes | P1 | Низкая | **Done** | FPS на слабых клиентах |
| E7 | Proof HUD + CV RULE overlay | P0 | Средняя | **Done** | «Видно почему» |
| E8 | simulation tests jam/estop/c_priority | P1 | Низкая | **Done** | Регрессионная защита |
| E9 | Agent MVP + scripts | P1 | Средняя | **Done** | Ops / future autonomy |
| E10 | resolveItem SKU-*-LC | P2 | Низкая | **Done** | Стабильность данных |
| E11 | Унификация визуала `/` и `/details` | P1 | Высокая | **Open** | Единый образ системы |
| E12 | Redeploy prod dist на :3100 | P0 | Низкая (ops) | **Open** | Публичная демо актуальна |
| E13 | Playwright в CI (1 worker) | P2 | Средняя | **Open** | Авто-регрессия UI |
| E14 | Опциональный physics (Rapier lite) | P3 | Высокая | **Open** | Доп. fidelity (не блокер) |
| E15 | Agent auto-patch за human gate | P3 | Высокая | **Open** | Автономия уровня 2 |
---
## 4. Приоритет (матрица)
| Приоритет | Фокус |
| --------- | ----- |
| P0 | То, без чего живой показ врёт или ломается: классификация, proof, faults, controls, prod sync |
| P1 | Убедительность и стабильность: quality, tests, twin unify, agent ops |
| P2 | Удобство и покрытие: e2e CI, data edge cases |
| P3 | Исследования: real physics, full autonomous implementer |
---
## 5. Ожидаемый эффект по направлениям
| Направление | Эффект Done-этапов | Остаточный разрыв |
| ----------- | ------------------ | ----------------- |
| Demo clarity | Высокий — seek/hotkeys/presentation | — |
| Algorithm proof | Высокий — live classify + HUD | Pseudo-CV всё ещё |
| Fault story | Высокий — jam/e-stop в playlist | — |
| Visual realism | Средний+ | Dual twin, нет AO/heavy PBR |
| Physics fidelity | Средний | Нет rigid body |
| Ops | Высокий — scripts + agent | Redeploy path вне docker CLI |
---
## 6. Сложность оставшихся работ
| Работа | Сложность | Зависимости | Риск |
| ------ | --------- | ----------- | ---- |
| Unify twins | Высокая | Общий scene kit, не ломая оба маршрута | Регрессия `/details` |
| Prod redeploy | Низкая | Доступ к docker/host вне среды | Забыть обновить tunnel cache |
| e2e CI | Средняя | 1 worker, артефакты | Flaky screenshots |
| Rapier | Высокая | Performance budget | FPS падение |
| Agent patcher | Высокая | Safety limits, staging | Порча ветки |
---
## 7. Риски плана
| Риск | Митигация |
| ---- | --------- |
| Погоня за «настоящей физикой» убивает FPS | Держать кинематику; physics только opt-in |
| Унификация twin ломает details UX | Feature flag / поэтапный shared module |
| Агент без лимитов | Kill switch + forbid deploy |
| Показ со старым prod | `demo:health` + явный checklist redeploy |
---
## 8. Зависимости
```text
E12 (redeploy) зависит от зелёных tests/build на feature-ветке
E11 (unify) зависит от стабильного continuous twin (E1–E7 Done)
E13 (e2e CI) зависит от ёмкости (1 worker) и стабильных селекторов
E15 (agent patch) зависит от E9 + AI_AGENT_SAFETY_LIMITS
```
---
## 9. Критерии приёмки
### Must (для «максимальной демо» итерации)
- [x] Continuous использует `classifyItem` (не только playlist label).
- [x] Playlist ≥10 с jam и emergency_stop.
- [x] Proof HUD показывает DIM, K, reason.
- [x] Hotkeys + speed + seek + presentation работают.
- [x] Quality modes существуют и покрыты тестами.
- [x] Vitest зелёный (≥153).
- [x] Build OK.
- [x] Backup tag существует.
- [ ] Production https://arhipovdan.ru/ отдаёт новый dist (**Open**).
### Should
- [ ] Визуальный parity ключевых элементов `/` и `/details`.
- [ ] Playwright smoke в CI (1 worker).
### Could
- [ ] Лёгкий physics layer.
- [ ] Agent auto-patch с обязательным human merge.
---
## 10. Рекомендуемый порядок дожима
1. Redeploy production (E12) — максимальный ROI для жюри.
2. Visual unify twin (E11) — доверие «одной системы».
3. e2e smoke (E13).
4. Остальное — по необходимости.

159
docs/DEMO_RUNBOOK.md Normal file
View File

@@ -0,0 +1,159 @@
# Demo Runbook — OZON Tech Sorter Simulation
**Назначение:** провести живую демонстрацию жюри/заказчику без сюрпризов.
**Дата актуализации:** 2026-07-15
**Публичный URL:** https://arhipovdan.ru/
**Репозиторий:** `/home/coder/arhipovdan/app`
---
## 1. За 30–60 минут до показа
### 1.1. Остановить фоновые помехи
```bash
cd /home/coder/arhipovdan/app
node agent/cli.mjs stop
# убедиться, что Playwright/тяжёлые job не бегут
```
### 1.2. Зелёный baseline
```bash
npm test
npm run build
```
Ожидание: Vitest **153** passed / **16** files; build OK.
### 1.3. Health
```bash
npm run demo:health
```
Проверяет:
- `http://127.0.0.1:3100/` (prod loopback),
- `http://127.0.0.1:3101/` (preview, если поднят),
- `https://arhipovdan.ru/`,
- vitest.
### 1.4. Актуальный билд на том URL, который показываете
| Если показываете | Что сделать |
| ---------------- | ----------- |
| Локальный preview | `npm run demo:start` → http://127.0.0.1:3101/ |
| Публичный сайт | Убедиться, что :3100 отдаёт **новый** `dist` (ручной redeploy). Иначе жюри увидит старую версию. |
> В этой среде может не быть `docker` CLI — redeploy выполняется тем процессом, которым контейнер обычно обновляется на OwlPrime.
---
## 2. Старт одной командой
```bash
cd /home/coder/arhipovdan/app
npm run demo:start
```
Скрипт: при необходимости `npm ci`, `npm run build`, поднимает `vite preview` на **127.0.0.1:3101**.
Остановка:
```bash
npm run demo:stop
# reset: bash scripts/demo-reset.sh
```
---
## 3. Сценарий показа (рекомендуемый тайминг ~6–8 мин)
| Мин | Что делать | Что говорит оператор |
| --: | ---------- | -------------------- |
| 0:00 | Открыть `/`, включить Presentation (P/F) | «Цифровой двойник линии сортировки» |
| 0:20 | Дать continuous playback идти | «Товар едет → измеряется → классифицируется» |
| 1:00 | Указать Proof HUD (DIM, K, reason) | «Решение — правила classifyItem, не просто ролик» |
| 2:00 | Кейсы B → C → D | «Габариты / негабарит / круглое сечение» |
| 3:30 | Кейс c_priority | «C приоритетнее D» |
| 4:00 | Jam | «Затор — поток заморожен» |
| 4:40 | Emergency stop | «E-stop — safety stop» |
| 5:20 | Speed 0.5× на сложном кейсе | «Замедляем для разбора» |
| 5:50 | При необходимости `/details` | «Инженерный FSM и сенсоры» — осторожно: визуал twin другой |
| 6:30 | Q&A | Hotkeys 1–0 для прыжка к кейсу |
---
## 4. Hotkeys оператора
| Клавиша | Действие |
| ------- | -------- |
| Space | Пауза / продолжить |
| N | Следующий кейс |
| B | Предыдущий |
| R | Reset |
| P / F | Presentation / fullscreen |
| E | Журнал событий |
| 1–0 | Быстрый переход по кейсам |
Скорость: **0.5×–2×** в demo controls.
---
## 5. Playlist (10 кейсов) — шпаргалка
Порядок storytelling (см. `demoPlaylist.ts`):
1. Короб → **B**
2. ЛанчБокс → **B**
3. Негабарит → **C**
4. Мелкий item (ручка) → **C** (min dims)
5. Тарелка → **D** (K)
6. Бутылка → **D**
7. Oversized+round → **C** (priority)
8. (edge / доп. кейс по playlist)
9. **Jam**
10. **Emergency stop**
Точные id/SKU — в `src/domain/demoPlaylist.ts`.
---
## 6. Если что-то пошло не так
| Симптом | Действие |
| ------- | -------- |
| Чёрный экран / WebGL | Обновить страницу; проверить `ThreeCapabilityCheck`; снизить нагрузку (не demo на слабом GPU клиента) |
| «Не та» логика на сайте | Сравнить с preview :3101; вероятно устарел prod dist → redeploy |
| Завис после jam | R / следующий кейс; не паниковать — freeze ожидаем |
| Красные тесты утром | Не начинать показ; `npm test`, чинить на feature-ветке |
| Агент что-то пишет | `node agent/cli.mjs stop`; MVP не патчит, но stop обязателен |
| Нет сети к публичному URL | Показать loopback :3100 или preview :3101 |
Откат кода:
```bash
git checkout backup/pre-maximum-demo-realism-20260715
```
---
## 7. Что не обещать жюри
- «Настоящий CV с камеры» — нет, pseudo-CV.
- «Полный physics engine» — нет, кинематика.
- «Агент сам выкатывает в prod» — запрещено.
- «`/` и `/details` — идентичная 3D-сцена» — пока нет.
---
## 8. После показа
```bash
npm run demo:stop
node agent/cli.mjs resume # если нужен ночной dry-run
# или оставить stop до следующего окна обслуживания
```
Собрать feedback → занести в backlog агента / issues; не коммитить секреты.

199
docs/FULL_PROJECT_AUDIT.md Normal file
View File

@@ -0,0 +1,199 @@
# Полный аудит проекта — OZON Tech Sorter Simulation
**Дата аудита:** 2026-07-15
**Ветка:** `feature/maximum-demo-realism` (от `dan_branch` @ `e89c728`)
**Точка отката:** тег `backup/pre-maximum-demo-realism-20260715`
**Репозиторий:** `/home/coder/arhipovdan/app`
**Публичный URL:** https://arhipovdan.ru/
| Метка | Значение |
| ----- | -------- |
| Тип данных | Измерено / проверено в репозитории и на сервере |
| Статус | Frontend-only MVP, Track 3 (цифровой двойник сортировки) |
---
## 1. Описание проекта
**OZON Tech Sorter Simulation** — React/Vite/Three.js цифровой двойник промышленной сортировки товаров (Track 3). Система демонстрирует полный контур:
```text
Поступление объекта
→ обнаружение (pseudo-CV / сенсоры)
→ измерения и признаки (габариты, K-roundness)
→ classifyItem (детерминированные правила)
→ управляющий сигнал (gate / pusher)
→ кинематическое перемещение
→ маршрут B / C / D или fault
→ журнал событий + метрики
```
**Характер MVP:** только frontend. Backend, WebSocket, БД, API-сервер — отсутствуют. Сборка — статический `dist`, раздача через nginx (Docker-образ или локальный preview).
**Два движка демонстрации:**
| Маршрут | Движок | Назначение |
| ------- | ------ | ---------- |
| `/` | Continuous playback + playlist | Основная демо для жюри: непрерывный 3D twin, seek/speed, hotkeys |
| `/details` | State-machine simulation | Инженерный разбор: FSM, сенсоры, PID, сценарии |
Оба движка используют общий `classifyItem` и доменные типы, но **визуальные 3D-сцены всё ещё различаются** (`SorterDigitalTwinContinuous` vs `SorterDigitalTwin`).
---
## 2. Архитектура
```text
src/data/items.ts, scenarios.ts, resolveItem.ts, modelAssets.ts
|
v
src/domain/classifier.ts ← единый источник решения (B/C/D)
|
+-- continuousPlayback.ts + demoPlaylist.ts + measurementSystem.ts → MainPage (/)
|
+-- simulation.ts + metrics/pid/sensors → DetailsPage (/details)
|
v
React UI + R3F (Three.js) + Proof HUD / CV overlay / EventLog
```
**Деплой (production-контур):**
```text
Vite build → dist/
→ Docker (node:20-alpine build + nginx:alpine runtime)
→ nginx слушает 127.0.0.1:3100 на хосте OwlPrime
→ cloudflared tunnel → https://arhipovdan.ru/
```
В текущем окружении **нет docker CLI** для оператора; Node 20.20.2 используется для локальной сборки. Production-контейнер мог быть поднят вне этой среды — см. риск устаревшего `dist` на :3100.
---
## 3. Карта модулей
| Область | Путь | Роль |
| ------- | ---- | ---- |
| Точка входа | `src/main.tsx`, `src/App.tsx` | Router: `/`, `/details` |
| Continuous demo | `src/domain/continuousPlayback.ts` | Фазы кейса, таймлайн, fault freeze |
| Playlist | `src/domain/demoPlaylist.ts` | 10 кейсов (классификация + jam + e-stop) |
| Измерения | `src/domain/measurementSystem.ts` | Stepper/laser/stereo → `classifyItem` |
| Классификатор | `src/domain/classifier.ts` | `DIMENSION_LIMITS`, приоритет C над D |
| Кинематика | `src/domain/physicalItemMotion.ts` | Путь по сети конвейера, jitter, freeze |
| Layout | `src/domain/physicalLayout.ts`, `conveyorNetwork.ts` | Единицы мм/м, геометрия линий |
| Качество | `src/domain/qualityMode.ts` | low / medium / high / demo |
| FSM sim | `src/domain/simulation.ts` | State machine для `/details` |
| 3D continuous | `src/components/ThreeD/SorterDigitalTwinContinuous.tsx` | Основной twin |
| 3D details | `src/components/ThreeD/SorterDigitalTwin.tsx` | Инженерный twin |
| Proof UI | `CurrentProofCard`, `CVInspectionOverlay` | DIM / K / reason / RULE |
| Agent MVP | `agent/cli.mjs` | dry-run / run-once / status / stop… |
| Demo scripts | `scripts/demo-*.sh`, `scripts/agent-*.sh` | One-command ops |
---
## 4. Текущий стек
| Слой | Технология | Примечание |
| ---- | ---------- | ---------- |
| Bundler | Vite | Production build ~сотни ms |
| UI | React 19 + TypeScript | SPA |
| 3D | Three.js + @react-three/fiber + drei | Клиентский WebGL |
| Тесты | Vitest | Unit/domain; e2e Playwright — вручную |
| Контейнер | Docker multi-stage + nginx | Статический хостинг |
| Runtime на сервере | nginx :3100, cloudflared | Без pm2 в этой среде |
| Node (build) | 20.20.2 | Измерено |
**Чего нет (подтверждено аудитом):** backend, БД, WebSocket/SSE, PM2, docker CLI в текущем shell-окружении, CI e2e, реальный ML/CV, физический движок (Rapier/Cannon и т.п.).
**Секреты:** файл `.env` присутствует (ключи `login`, `password`, `url`). Значения **не документируются** и в отчёты не включаются.
---
## 5. Выявленные проблемы
| # | Проблема | Критичность | Влияние на демо |
| - | -------- | ----------- | --------------- |
| P1 | Dual 3D twins визуально расходятся (`/` vs `/details`) | Высокая | Зритель может не понять «одну систему» |
| P2 | Нет реального physics engine — детерминированная кинематика | Средняя | При пристальном взгляде нет столкновений/инерции «как в жизни» |
| P3 | Pseudo-CV (измерения из данных SKU, не с камеры) | Средняя | Нужен Proof HUD, иначе «анимация» |
| P4 | Production :3100 может отдавать старый `dist` до redeploy | Высокая | Публичная демо ≠ локальная сборка |
| P5 | Нет e2e в CI; Playwright только scripts | Средняя | Регрессии UI ловятся вручную |
| P6 | Agent MVP не патчит код автоматически | Низкая (by design) | Автономность ограничена verify-only |
| P7 | GPU на сервере idle; 3D на клиенте | Инфо | Серверный offscreen render не нужен |
---
## 6. Критичность (сводка)
| Уровень | Количество | Действие |
| ------- | ---------: | -------- |
| Критическая для живого показа | 1 | Синхронизировать/передеплоить prod dist |
| Высокая (доверие демо) | 2 | Унификация twin + явный proof алгоритма (уже частично сделано) |
| Средняя (техдолг) | 3 | Physics/CV/e2e — план, не блокер MVP |
| Низкая / by design | 1 | Agent без auto-merge |
---
## 7. Технический долг
1. **Два рендерера сцены** — дублирование материалов/освещения/лейаута.
2. **Кинематика вместо физики** — осознанный trade-off производительности и детерминизма.
3. **Pseudo-CV** — confidence фиксирован (0.65 в measurement path после фикса min dims); нет модели.
4. **Ручные Playwright-скрипты** в `scripts/` без интеграции в CI.
5. **Agent** — оркестратор без Implementer-патчей (verify-only).
6. **Документация историческая** в `docs/*_REPORT.md` — много итерационных отчётов; этот аудит — актуальная точка истины на 2026-07-15.
---
## 8. Состояние тестов
| Метрика | До изменений | После изменений | Тип данных |
| ------- | -----------: | --------------: | ---------- |
| Passed | 144 | **153** | Измерено |
| Файлов тестов | 14 | **16** | Измерено |
| Runner | Vitest | Vitest | — |
Добавлено/расширено: `simulation.test.ts` (jam / emergency_stop / c_priority), тесты quality mode и связанные domain-тесты.
**E2E:** не в CI. Скрипты Playwright/Python в `scripts/` — ручной прогон (**оценка процесса**, не автоматический gate).
---
## 9. Состояние production build
| Метрика | До | После | Тип |
| ------- | -- | ----- | --- |
| `npm run build` | OK (~391 ms) | OK | Измерено |
| Main R3F chunk | ~881 kB | (сборка OK; детальный breakdown см. PERFORMANCE_BASELINE) | Измерено / частично |
| CSS | — | 39.66 kB (gzip 8.79) | Измерено |
| Continuous twin chunk | — | 51.29 kB (gzip 13.68) | Измерено |
Команда: `tsc -b && vite build`. Typecheck входит в build pipeline.
---
## 10. Состояние демонстрации
**Сильные стороны (после итерации maximum-demo-realism):**
- `classifyItem` встроен в continuous playback — live classification, не только playlist override.
- Playlist 10 кейсов: B/C/D, edge, c_priority, jam, emergency_stop.
- Demo controls: seek, speed 0.5–2×, hotkeys (Space/N/B/R/P/E/F/1–0), presentation mode, event journal.
- Proof HUD: DIM pass/fail, K, classifier reason; CV overlay с RULE.
- Quality modes: low / medium / high / demo.
- Fault freeze/recover в `physicalItemMotion` + seeded jitter.
- One-command: `npm run demo:start` / `demo:health` / agent scripts.
**Ограничения для жюри:**
- Публичный https://arhipovdan.ru/ может ещё показывать старый билд, пока не пересобран/не перезалит контейнер на :3100.
- Визуальное отличие `/` и `/details`.
- Нет настоящего ML-CV и rigid-body physics.
**Готовность к показу:** высокая для локального preview (`127.0.0.1:3101` через `demo:start`) при зелёных тестах; production — после явного redeploy.
---
## 11. Вывод аудита
Проект — зрелый frontend digital twin с убедительным демо-контуром и измеримой proof-логикой классификации. Главные остаточные риски для показа: **синхронизация production dist** и **визуальная унификация двух twin**. Автономный агент на сервере — **возможен с ограничениями** (1 worker, hybrid LLM, без auto-deploy). Подробности — в `SERVER_CAPACITY_REPORT.md` и `AUTONOMOUS_AI_AGENT_ARCHITECTURE.md`.

View File

@@ -0,0 +1,173 @@
# Отчёт о реализации — maximum-demo-realism
**Ветка:** `feature/maximum-demo-realism`
**База:** `dan_branch` @ `e89c728`
**Backup tag:** `backup/pre-maximum-demo-realism-20260715`
**Дата:** 2026-07-15
**Проект:** OZON Tech Sorter Simulation (Track 3)
---
## 1. Цель итерации
Максимально поднять убедительность живой демонстрации: live-классификация, safety-сценарии, proof UI, управление показом, адаптивное качество, ops-скрипты и безопасный MVP агента — без выдуманных секретов и без auto-deploy.
---
## 2. Все выполненные изменения (реальные)
| # | Изменение | Зачем |
| - | --------- | ----- |
| 1 | `classifyItem` встроен в continuous playback | Live classification, не только подписи playlist |
| 2 | `measurementSystem` → `DIMENSION_LIMITS` + `classifyItem`; min dims; confidence 0.65 | Согласованность измерений и правил |
| 3 | Playlist 8→10: jam + emergency_stop timelines | Safety story для жюри |
| 4 | `physicalItemMotion`: fault freeze/recover + seeded jitter | Правдоподобие и воспроизводимость |
| 5 | Demo controls: seek, speed 0.5–2×, hotkeys Space/N/B/R/P/E/F/1–0, presentation, event journal | Управление живым показом |
| 6 | Quality modes low/medium/high/demo | FPS на разных клиентах |
| 7 | Proof HUD: DIM pass/fail, K, reason; CV overlay RULE | Доказательство работы алгоритма |
| 8 | `simulation.test.ts`: jam / estop / c_priority | Регрессия safety/логики |
| 9 | Agent MVP `agent/cli.mjs`: dry-run\|run-once\|status\|stop\|resume\|pause\|report | Автономия уровня verify-only |
| 10 | Scripts: demo-start/stop/reset/health, agent-dry-run, agent-run-once | One-command ops |
| 11 | `resolveItem` для SKU-*-LC | Стабильность данных |
---
## 3. Изменённые / затронутые области файлов
> Точный `git diff` зависит от незакоммиченного состояния рабочей копии. Ниже — карта модулей по смыслу изменений (**проверено по коду репозитория**).
| Область | Файлы (ключевые) |
| ------- | ---------------- |
| Continuous / classify | `src/domain/continuousPlayback.ts`, `measurementSystem.ts`, `classifier.ts` |
| Playlist / faults | `src/domain/demoPlaylist.ts`, `physicalItemMotion.ts`, `seededRng.ts` |
| UI demo | `src/pages/MainPage.tsx`, Proof/CV components, styles |
| Quality | `src/domain/qualityMode.ts`, `qualityMode.test.ts` |
| Data | `src/data/resolveItem.ts` |
| Tests | `src/domain/simulation.test.ts`, связанные domain tests |
| Agent | `agent/cli.mjs`, `agent/state/*`, `agent/reports/*` |
| Scripts | `scripts/demo-*.sh`, `scripts/agent-*.sh` |
| Package scripts | `package.json` (`demo:*`, `agent:*`) |
| Docs | этот набор `docs/*.md` аудита |
---
## 4. Причины изменений (кратко)
1. Жюри должно **видеть причинно-следственную связь** измерений → правила → маршрут.
2. Без jam/e-stop демо выглядит «идеальной анимацией».
3. Без hotkeys/presentation оператор теряет контроль на сцене.
4. Без quality modes слабые ноутбуки дают рывки и подрывают доверие.
5. Agent/scripts нужны для устойчивой эксплуатации и будущего цикла улучшений **с лимитами**.
---
## 5. Результаты тестов
| Проверка | До | После | Тип |
| -------- | -: | ----: | --- |
| Vitest passed | 144 | **153** | Измерено |
| Test files | 14 | **16** | Измерено |
| E2E CI | нет | нет | Измерено |
| Lint (отдельный) | не выделен в package | не выделен | Измерено |
| Typecheck | через `tsc -b` в build | OK вместе с build | Измерено |
---
## 6. Метрики до и после
| Метрика | До | После | Изменение |
| ------- | -: | ----: | --------: |
| Tests | 144 | 153 | +9 |
| Test files | 14 | 16 | +2 |
| Build | OK ~391 ms | OK | стабильно |
| CSS | — | 39.66 kB / gzip 8.79 | зафиксировано |
| Continuous twin chunk | — | 51.29 kB / gzip 13.68 | зафиксировано |
| Playlist size | 8 | 10 | +faults |
| Agent | нет | MVP CLI | +ops |
| Live classify on `/` | слабо | wired | +proof |
Main R3F chunk baseline до итерации: ~881 kB (**Измерено** historically).
---
## 7. Оставшиеся ограничения
| Ограничение | Комментарий |
| ----------- | ----------- |
| Нет real physics engine | Детерминированная кинематика |
| Pseudo-CV | Synthetic measurements |
| Dual 3D twins diverge | `/` vs `/details` |
| Нет e2e в CI | Playwright вручную |
| Agent без auto-patch | By design MVP |
| Production :3100 | Может служить старый dist до redeploy |
| Нет docker CLI в этой среде | Redeploy — внешняя ops-процедура |
| GPU idle | Не используется для demo render |
---
## 8. Инструкции запуска
### Демо (preview, не путать с prod :3100)
```bash
cd /home/coder/arhipovdan/app
npm run demo:start # build + vite preview 127.0.0.1:3101
npm run demo:health # :3100 / :3101 / public + vitest
npm run demo:stop # остановить preview
# также: bash scripts/demo-reset.sh
```
### Разработка
```bash
npm install # при необходимости
npm run dev # 127.0.0.1:3100 (vite dev — не prod nginx)
npm test
npm run build
```
### Агент
```bash
npm run agent:dry-run
npm run agent:run-once
npm run agent:status
node agent/cli.mjs stop # перед живым показом
node agent/cli.mjs resume
node agent/cli.mjs report
```
### Откат кода
```bash
git fetch --tags
git checkout backup/pre-maximum-demo-realism-20260715
# или сброс ветки к e89c728 по необходимости (только осознанно)
```
### Production
Публичный URL: https://arhipovdan.ru/ (nginx loopback :3100 + cloudflared).
После merge/сборки нужен **ручной redeploy** образа/dist — агент этого не делает.
---
## 9. Hotkeys (оператору демо)
| Клавиша | Действие |
| ------- | -------- |
| Space | Play / pause |
| N | Next case |
| B | Back / previous |
| R | Reset |
| P / F | Presentation / fullscreen-related |
| E | Event journal focus/toggle (UI) |
| 1–0 | Seek/jump по кейсам playlist |
Speed: 0.5×–2× через demo controls UI.
---
## 10. Вывод
Итерация достигла измеримого улучшения демо-контура (тесты +9, playlist +faults, live classify, proof, controls, agent MVP). Критический остаточный ops-риск — **рассинхрон production dist**. Технический потолок реализма без смены архитектуры — кинематика + pseudo-CV; это задокументировано честно.

View File

@@ -0,0 +1,117 @@
# Базовая линия производительности (Performance Baseline)
**Дата:** 2026-07-15
**Ветка:** `feature/maximum-demo-realism`
**Команды:** `npm test`, `npm run build`
Легенда: **Измерено** · **Оценка** · **Не измерено в этом прогоне** (клиентский FPS на железе жюри).
---
## 1. Тесты
| Метрика | Baseline до изменений | После изменений | Тип |
| ------- | --------------------: | --------------: | --- |
| Passed assertions/tests | 144 | **153** | Измерено |
| Test files | 14 | **16** | Измерено |
| Runner | Vitest | Vitest | — |
| Результат | green | green | Измерено |
Дельта: +9 тестов, +2 файла (в т.ч. расширенный `simulation.test.ts`, `qualityMode.test.ts` и связанные).
---
## 2. Production build
| Метрика | До | После | Тип |
| ------- | -- | ----- | --- |
| Build status | OK | OK | Измерено |
| Build time | ~391 ms | OK (порядок сотен ms) | Измерено / частично |
| Pipeline | `tsc -b && vite build` | то же | Измерено |
### Размеры артефактов (после)
| Артефакт | Raw | Gzip | Тип |
| -------- | --: | ---: | --- |
| CSS | 39.66 kB | 8.79 kB | Измерено |
| Continuous twin JS chunk | 51.29 kB | 13.68 kB | Измерено |
| Main R3F-related chunk (до итерации) | ~881 kB | — | Измерено (baseline до) |
> Точный полный rollup всех чанков «после» зависит от конкретного `vite build` output; CSS и continuous twin зафиксированы аудитом. Main Three/R3F chunk исторически доминирует по весу — это ожидаемо.
---
## 3. Runtime (клиент)
| Метрика | Ожидание / факт | Тип |
| ------- | --------------- | --- |
| Рендер 3D | WebGL в браузере клиента | Измерено (архитектура) |
| Серверный 3D | Не используется | Измерено |
| Target FPS demo/high | 60 | Измерено (presets) |
| Target FPS low/medium | 30 | Измерено |
| Shadows / effects | Выключены в presets | Измерено |
| Adaptive quality | `detectQualityMode` / `adaptQuality` | Измерено |
| Фактический FPS 1080p на GTX клиента жюри | Зависит от клиента | **Не измерено** здесь |
Сервер (OwlPrime) при раздаче статики: load ~0.5–0.6 — **не** является bottleneck FPS (**Измерено** нагрузка хоста).
---
## 4. Качество vs производительность (trade-offs)
| Рычаг | Влияние на FPS | Влияние на реализм |
| ----- | -------------- | ------------------ |
| dprMax 1→1.5 | − | + резкость |
| antialias | − | + края |
| shadows on | −− | + контакт с лентой |
| effects/AO | −−− | + «кино» |
| maxVisibleItems | + при снижении | − плотность потока |
| rollerDetail none/sparse | + | − механика роликов |
| Static rollers (perf commit) | + | − вращение |
Текущая политика: **сначала стабильный FPS**, затем дозированный реализм.
---
## 5. Сравнение до / после (сводка)
| Метрика | До | После | Изменение |
| ------- | -: | ----: | --------: |
| Tests passed | 144 | 153 | +9 |
| Test files | 14 | 16 | +2 |
| Build | OK ~391ms | OK | стабильно |
| Demo playlist cases | 8 | 10 | +2 (faults) |
| Live classify on `/` | playlist-heavy | wired `classifyItem` | качество демо ↑ |
| Quality modes | не как система | low…demo | +адаптация |
| CSS gzip | — | 8.79 kB | зафиксировано |
| Continuous chunk gzip | — | 13.68 kB | зафиксировано |
---
## 6. Нагрузка инструментов разработки на сервере
| Инструмент | Оценка стоимости | Рекомендация |
| ---------- | ---------------- | ------------ |
| `npm test` | Умеренная CPU, минуты | OK on-demand |
| `npm run build` | Короткая CPU | OK |
| Playwright 1 worker | Высокая RAM | Не во время демо |
| Local LLM 7B | Очень высокая VRAM/RAM | Избегать на хосте демо |
| Agent dry-run | = tests+build | Лимит 1 worker |
---
## 7. Регрессионные триггеры (когда обновлять baseline)
Переснять baseline, если:
- включены shadows/effects в default demo;
- добавлен physics engine;
- вырос main chunk >20%;
- FPS жалобы на 1366×768;
- изменён continuous twin chunk существенно.
---
## 8. Вывод
Производительность MVP **приемлема** для статического хостинга и клиентского WebGL. Бюджет сознательно защищён отключёнными тенями/эффектами. Главный риск FPS — будущие визуальные «улучшения без лимитов», а не текущий nginx.

View File

@@ -0,0 +1,129 @@
# Аудит физической достоверности
**Дата:** 2026-07-15
**Принцип:** не выдавать красивую анимацию за физическую симуляцию.
Разделение слоёв:
| Слой | Реализация в проекте |
| ---- | -------------------- |
| Визуальный реализм | R3F materials / STL / camera |
| Физическая достоверность | Детерминированная кинематика (`physicalItemMotion`, conveyor network) |
| Логика системы | `classifyItem`, FSM `simulation`, measurement stages |
| Презентационный слой | Playlist, hotkeys, presentation mode, Proof HUD |
---
## 1. Единицы и layout
| Величина | Источник | Статус |
| -------- | -------- | ------ |
| мм / м | `physicalLayout.ts` (`MM_PER_STEP`, высоты лазера, `BELT_TOP_Y`) | Измерено |
| Сеть конвейера | `conveyorNetwork.ts` / path | Измерено |
| Габариты SKU | `items.ts` + `resolveItem` (в т.ч. SKU-*-LC) | Измерено |
| Лимиты габаритов | `DIMENSION_LIMITS` в `classifier.ts` | Измерено |
**Вывод:** единицы согласованы в domain-слое. Это **кинематическая** согласованность, не динамика Ньютона.
---
## 2. Что является «настоящей» логикой vs аппроксимацией
| Узел контура | Реальность в MVP | Тип |
| ------------ | ---------------- | --- |
| Поступление объекта | Playlist / scenario spawn | Детерминированные данные |
| Обнаружение | Phase/sensor flags + pseudo-CV | Аппроксимация |
| Измерения | Модель stepper/laser/stereo из известных размеров | Аппроксимация (честно показана в UI) |
| Классификация | `classifyItem` правила + приоритет C>D | **Реальная логика** |
| Управляющий сигнал | Gate/pusher commands | Реальная логика FSM / playback phases |
| Перемещение | Параметрический путь + speed + fault freeze | Кинематика |
| Столкновения / трение | Нет rigid-body | Отсутствует |
| Подтверждение результата | Category + event log + metrics | Реальная логика учёта |
| Jam / E-stop | Fault timelines + freeze/recover | Симулированные safety-сценарии |
---
## 3. Кинематика предметов
Модуль `physicalItemMotion.ts`:
| Свойство | Поведение | Зачем |
| -------- | --------- | ----- |
| Path following | Движение по сегментам сети | Промышленный маршрут |
| Fault freeze | Остановка при jam/e-stop | Safety demo |
| Recover | Возобновление после reset-потока | Живой показ не «умирает» |
| Seeded jitter | Воспроизводимый шум позиции | Меньше «робот-идеал» |
| Speed scale | 0.5–2× от demo controls | Презентация |
**Нет:** импульсов, restitution, stacking, проскальзывания ленты как friction model, расчёта момента инерции.
---
## 4. Измерительная подсистема
`measurementSystem.ts` моделирует стадии:
`idle → leading_edge → step_counting → laser_height → stereo_width_shape → decision_ready → command_sent`
После доработки:
- использует `DIMENSION_LIMITS` + `classifyItem`;
- исправлены min dimensions;
- confidence **0.65** (зафиксировано в реализации measurement path);
- наружу отдаётся `classificationReason` для Proof HUD.
Это **инженерная визуализация измерений**, а не поток с реальной камеры.
---
## 5. Fault physics vs fault logic
| Сценарий | Логика | Физика движения |
| -------- | ------ | --------------- |
| Jam | Playlist `faultType: jam` + tests | Freeze на конвейере |
| Emergency stop | `emergency_stop` | Freeze; требуется recover/reset narrative |
| C priority | `classifyItem` + sim tests | Маршрут C даже при roundness |
Тесты: `simulation.test.ts` покрывает jam / estop / c_priority (**Измерено**: рост 144→153 тестов).
---
## 6. Инварианты, которые должны держаться
| Инвариант | Статус |
| --------- | ------ |
| Решение на continuous = `classifyItem(item)` | Wired (**Done**) |
| C приоритетнее D при oversized+round | Покрыто тестами |
| Min/max dimensions согласованы с UI Proof | Done (DIMENSION_LIMITS) |
| При fault скорость транспорта = 0 (freeze) | Done |
| Jitter детерминирован seed’ом | Done |
| Нет «телепорта» вне path network | Ожидается; регрессии ловятся visual QA вручную |
---
## 7. Оценка fidelity
| Категория | Балл (0–100) | Тип | Пояснение |
| --------- | -----------: | --- | --------- |
| Logical fidelity | 85 | Оценка | Сильный classifier + FSM |
| Kinematic fidelity | 70 | Оценка | Хороший path, слабые контакты |
| Dynamic fidelity | 25 | Оценка | Нет physics engine |
| Sensor fidelity | 55 | Оценка | Стадии есть, данные synthetic |
| Safety fidelity | 75 | Оценка | Jam/e-stop видимы и тестируются |
*(Баллы — экспертная **оценка**, не бенчмарк.)*
---
## 8. Рекомендации (без иллюзий)
1. **Не** подключать тяжёлый physics engine перед живым показом — риск FPS.
2. Держать честные подписи: «псевдо-CV», «кинематика».
3. При желании повысить fidelity: лёгкие contact constraints только на gate/pusher (opt-in demo mode).
4. Унифицировать twin, чтобы physics story не расходилась визуально между страницами.
---
## 9. Вывод
Проект честно находится в зоне **deterministic kinematic digital twin** с **реальной rule-based классификацией**. Это достаточно для Track 3 MVP и жюри, если proof-слой включён. Называть систему «физическим симулятором с CV» без оговорок — нельзя.

107
docs/RISK_REGISTER.md Normal file
View File

@@ -0,0 +1,107 @@
# Реестр рисков (Risk Register)
**Проект:** OZON Tech Sorter Simulation
**Дата:** 2026-07-15
**Ветка:** `feature/maximum-demo-realism`
Шкала: вероятность / влияние = Low · Medium · High · Critical.
Статус: Open · Mitigated · Accepted.
---
## 1. Сводная таблица
| ID | Риск | Вероятность | Влияние | Статус | Митигация |
| -- | ---- | ----------- | ------- | ------ | --------- |
| R01 | Production :3100 / https://arhipovdan.ru/ отдаёт старый dist | High | Critical | Open | `demo:health`; ручной redeploy; показывать :3101 при сомнении |
| R02 | Визуальный разрыв `/` vs `/details` путает жюри | High | High | Open | Вести показ на `/`; unify twins в плане |
| R03 | Жюри воспринимает кинематику как «фейк» | Medium | High | Mitigated | Proof HUD + честные формулировки; jam/e-stop |
| R04 | Pseudo-CV раскрыт как «обман» | Medium | Medium | Accepted | RULE overlay + confidence; не обещать ML |
| R05 | Просадка FPS на ноутбуке жюри | Medium | High | Mitigated | quality modes; shadows/effects off |
| R06 | Регрессия classifier/min dims | Low | Critical | Mitigated | tests 153; measurement+DIMENSION_LIMITS |
| R07 | Fault freeze без recover ломает показ | Low | High | Mitigated | recover path + hotkeys R/N |
| R08 | Agent/фоновые job портят ресурсы во время демо | Medium | High | Mitigated | kill switch; runbook stop |
| R09 | Будущий auto-patch агента ломает main | Low (сейчас) | Critical | Mitigated | forbid merge/deploy; MVP verify-only |
| R10 | Утечка секретов `.env` в отчёты/логи | Low | Critical | Mitigated | policy forbidSecretAccess; не документировать values |
| R11 | Нет e2e в CI — UI регрессия незамечена | Medium | Medium | Open | ручные scripts; план CI 1 worker |
| R12 | OOM при локальной LLM + Playwright | Medium | High | Accepted (avoid) | Variant C; не совмещать |
| R13 | Disk fill отчётами/скриншотами | Low | Medium | Open | ротация reports |
| R14 | Нет docker CLI в operator env | High (факт) | Medium | Accepted | внешний deploy path документирован |
| R15 | Swap thrash под нагрузкой | Low | High | Mitigated | лимиты 1 worker; demo mode без фона |
| R16 | Расхождение playlist expectedCategory и classifyItem | Low | High | Mitigated | wire classifyItem; tests |
| R17 | STL/fallback выглядят «игрушечно» | Medium | Low | Accepted | modelAssets notes; backlog textures |
| R18 | Tunnel/cloudflared outage | Low | Critical | Open | fallback loopback :3100 / LAN preview |
| R19 | Несогласованность документации и кода | Medium | Low | Mitigated | этот пакет docs = snapshot 2026-07-15 |
| R20 | Попытка «добавить physics» перед показом → регрессия | Medium | High | Open | запрет P0-physics перед demo day |
---
## 2. Детали по критическим рискам
### R01 — Устаревший production dist
**Симптом:** локально proof/hotkeys есть, на https://arhipovdan.ru/ — нет.
**Детектор:** сравнить UI; `demo:health`; hash файлов в контейнере (если доступен docker на хосте).
**Реакция:** ручной redeploy; на показе переключиться на проверенный preview.
**Тип данных о риске:** подтверждён аудитом как **процессный** факт («may still serve OLD dist»).
### R09 — Автономный агент vs production
**Симптом:** гипотетический merge/deploy без человека.
**Текущий контроль:** `forbidMergeToMain`, `forbidProductionDeploy`, нет Implementer auto-patch.
**Остаточный риск:** появится при расширении MVP без обновления safety caps.
### R10 — Секреты
`.env` содержит ключи `login`, `password`, `url`. Значения не подлежат публикации. Любой новый tooling обязан редact’ить env.
---
## 3. Риски ёмкости (связь с SERVER_CAPACITY_REPORT)
| Риск | Вывод |
| ---- | ----- |
| 24/7 agent | Возможен **с ограничениями** |
| Local 7B+ | Тяжело; предпочтителен API |
| Playwright | Да, 1 worker |
| CV training | Лучше external GPU |
| Server 3D | Не нужен |
---
## 4. Матрица приоритета обработки
```text
Сначала: R01 (prod sync), R18 (tunnel fallback plan)
Потом: R02 (twin unify), R11 (e2e), R13 (disk hygiene)
Следить: R05/R08 во время каждого показа
Не трогать в demo week: R20 (physics spike)
```
---
## 5. Accepted risks (осознанно)
| ID | Почему принимаем |
| -- | ---------------- |
| R04 | Архитектура MVP Track 3 — pseudo-CV by design |
| R12 | Не запускаем локальную LLM 24/7 |
| R14 | Ограничение окружения; обход через внешний deploy |
| R17 | ROI текстур ниже proof/controls |
---
## 6. Триггеры пересмотра реестра
- Смена хоста/GPU/RAM.
- Включение Implementer auto-patch.
- Добавление physics engine.
- Подключение реального CV inference.
- Появление CI e2e.
- Инцидент на живом показе.
---
## 7. Вывод
Главный необработанный операционный риск для жюри — **R01 (старый prod dist)**. Технические риски демо-контура в основном **смягчены** итерацией maximum-demo-realism. Риски полной автономии агента **заблокированы политикой**, пока MVP verify-only.

View File

@@ -0,0 +1,176 @@
# Отчёт о ёмкости сервера
**Хост:** OwlPrime (контейнеризованный Ubuntu 24.04)
**Дата измерений:** 2026-07-15
**Приложение:** OZON Tech Sorter Simulation → nginx `127.0.0.1:3100`, tunnel → https://arhipovdan.ru/
Легенда типов данных: **Измерено** = получено диагностикой на сервере; **Оценка** = вывод по мощности без полного бенчмарка нагрузки.
---
## 1. Точные характеристики сервера
| Ресурс | Фактическое значение | Тип |
| ------ | -------------------: | --- |
| CPU | Intel i5-9400F, 6 ядер, 2.9–4.1 GHz | Измерено |
| RAM | 15 GiB (≈13 GiB available) | Измерено |
| Swap | 15 GiB | Измерено |
| Диск | NVMe ~452 G, ~201 G свободно (~54% used) | Измерено |
| GPU | 2× NVIDIA GTX 1080 8 GB, driver 580.126.09, CUDA 13.0 | Измерено |
| GPU load | idle | Измерено |
| Load average | ~0.5–0.6 | Измерено |
| OS | Ubuntu 24.04 (containerized) | Измерено |
| Node (build env) | 20.20.2 | Измерено |
| Docker CLI в этой среде | отсутствует | Измерено |
| PM2 | отсутствует | Измерено |
| App listen | nginx 127.0.0.1:3100 | Измерено |
| Public | cloudflared → https://arhipovdan.ru/ | Измерено |
| Git repo | `/home/coder/arhipovdan/app` | Измерено |
---
## 2. Текущая нагрузка
| Показатель | Значение | Вывод |
| ---------- | -------: | ----- |
| Load avg | 0.5–0.6 при 6 cores | Большой запас CPU |
| GPU | idle | Можно зарезервировать под LLM/CV, но с осторожностью |
| Disk free | ~201 G | Достаточно для node_modules, dist, Playwright cache, артефактов агента |
| Swap | 15 GiB | Есть подушка, но swap thrash недопустим для демо |
**Оценка:** сервер сейчас в «лёгком» режиме (статика nginx + tunnel). Основная 3D-нагрузка — на **клиентском** WebGL, не на сервере.
---
## 3. Доступные ресурсы (безопасный остаток)
| Ресурс | Оценка свободного бюджета | Тип |
| ------ | ------------------------: | --- |
| CPU | 4–5 ядер можно отдавать фону при лимите 1 тяжёлого worker | Оценка |
| RAM | ~8–10 GiB «мягкий» бюджет до давления на swap | Оценка |
| VRAM (2×8 GB) | теоретически хватает на 7B quant; на практике тяжело и конкурирует | Оценка |
| Disk | десятки GB под кэши/отчёты без риска | Оценка |
---
## 4. Допустимые фоновые процессы
| Процесс | Допустимо 24/7? | Условия |
| ------- | --------------- | ------- |
| nginx + cloudflared (prod static) | Да | Без изменения без явного deploy |
| Vite preview :3101 (demo) | Краткосрочно | Не путать с prod :3100 |
| Vitest / build по запросу | Да | Последовательно, не параллельно с LLM |
| Playwright Chromium (1 worker) | Да, по расписанию | Не во время живого показа жюри |
| Agent MVP (verify-only) | Да, с лимитами | См. ниже |
| Локальная LLM 7B+ | Только эксперименты | Предпочтительно внешний API |
| CV training | Нет как 24/7 | Вынести на dedicated GPU / внешний |
| Server-side Three.js offscreen | Возможно, не нужно | Клиентский WebGL достаточен |
---
## 5. Возможность локальных моделей (LLM)
| Вариант | Вердикт | Комментарий |
| ------- | ------- | ----------- |
| Локальная 7B+ на 2×1080 | **Возможна технически, тяжело** | VRAM суммарно 16 GB; квантизация нужна; CPU/RAM конкурируют с Playwright |
| Внешний LLM API | **Рекомендуется** | Hybrid Variant C |
| Полностью локальный агент (Variant A) | Не рекомендуется на этом хосте | Риск OOM / деградации демо |
**Вывод:** локальный инференс — опциональный research-path; production-агент должен использовать **внешний API** с бюджетом.
---
## 6. Возможность Playwright / Chromium
| Критерий | Вердикт |
| -------- | ------- |
| CPU + RAM | Достаточно (**Измерено** ресурсы; **Оценка** нагрузки) |
| Параллелизм | **1 worker** |
| 24/7 непрерывный прогон | Нежелателен; лучше nightly / по событию |
| Конфликт с живой демо | Высокий — не запускать во время показа |
---
## 7. Возможность автономного агента
**Однозначный вывод: возможен с ограничениями.**
| Параметр | Лимит |
| -------- | ----- |
| Parallel workers | 1 |
| LLM | Hybrid (внешний API primary) |
| Auto merge to main | Запрещено |
| Auto production deploy | Запрещено |
| Режим MVP | verify-only (dry-run / run-once), без auto-patch |
| Kill switch | `agent/state/KILL` |
Подробности: `AI_AGENT_SAFETY_LIMITS.md`, `AUTONOMOUS_AI_AGENT_ARCHITECTURE.md`.
---
## 8. Рекомендуемые лимиты
| Лимит | Значение | Источник |
| ----- | -------: | -------- |
| maxParallelWorkers | 1 | Agent MVP + ёмкость |
| maxCycleMinutes | 25 | `agent/cli.mjs` LIMITS |
| maxChangedFiles | 12 | Agent LIMITS |
| maxDiffLines | 800 | Agent LIMITS |
| dailyLlmBudgetUsd | 5 | Agent LIMITS |
| Playwright workers | 1 | Capacity |
| CPU soft cap для агента | ≤50% одного ядра в idle-poll; burst на test/build | Оценка |
| RAM soft cap агент+Chromium | ≤4 GiB | Оценка |
| Запрет | merge main, prod deploy, чтение секретов в логи | Policy |
---
## 9. Режимы эксплуатации
| Режим | Что запущено | Параллелизм | Назначение |
| ----- | ------------ | ----------: | ---------- |
| Минимальный безопасный | nginx :3100 + tunnel | 0 background jobs | Стабильный публичный показ |
| Оптимальный | + редкие `agent dry-run`, nightly tests | 1 | Поддержание качества |
| Максимальный | + Playwright 1w + внешний LLM | 1 | Исследования (не во время демо) |
| Демонстрация | Только prod или preview; агент STOP | 0 | Живое жюри |
| Автономное AI-улучшение | Agent + external LLM, ветки feature/*, no deploy | 1 | Улучшения с human gate |
---
## 10. Сводная таблица ёмкости
| Ресурс | Фактическое значение | Текущая нагрузка | Безопасный лимит | Вывод |
| ------ | -------------------: | ---------------: | ---------------: | ----- |
| CPU 6c | i5-9400F | load ~0.5–0.6 | 1 тяжёлый worker | Запас есть |
| RAM 15 GiB | ≈13 available | низкая | ≤4 GiB агент+browser | OK |
| Swap 15 GiB | — | не давить | Избегать thrash | OK как подушка |
| Disk ~452G | ~201G free | 54% used | Оставить ≥50G free | OK |
| GPU 2×1080 | idle | 0% | Не для prod demo loop | LLM/CV опционально |
| Playwright | — | нет | 1 worker | Да |
| Agent 24/7 | — | MVP | с ограничениями | Да |
| Local LLM 7B+ | — | нет | эксперимент | Тяжело; лучше API |
| CV training | — | нет | external | Не на этом хосте 24/7 |
| Server 3D | — | нет | не требуется | Клиент WebGL |
---
## 11. Риски ёмкости
| Риск | Вероятность | Влияние | Митигация |
| ---- | ----------- | ------- | --------- |
| OOM при локальной LLM + Playwright | Средняя | Падение демо | Не совмещать; API LLM |
| Swap thrash во время показа | Низкая | Лаги tunnel/nginx | Режим «Демонстрация» = stop agent |
| Disk fill артефактами | Низкая | Сборка падает | Ротация `agent/reports`, screenshot dirs |
| Старый dist на :3100 | Высокая (процесс) | Жюри видит не то | Явный redeploy после merge |
| Нет docker CLI здесь | Факт | Сложнее ops | Документировать внешний deploy path |
---
## 12. Нужен ли дополнительный сервер?
| Вопрос | Ответ |
| ------ | ----- |
| Отдельный staging | Желателен при частом агенте; на текущем хосте можно эмулировать preview :3101 |
| Dedicated GPU server | Да, если цель — CV training / тяжёлый local LLM |
| Доп. сервер для static demo | Нет — текущий nginx достаточен |
**Итог:** для demo + ограниченного агента текущий сервер **достаточен**. Для тяжёлого ML — вынести.

View File

@@ -0,0 +1,115 @@
# Аудит визуального реализма
**Дата:** 2026-07-15
**Стек визуализации:** Three.js + React Three Fiber + drei (клиентский WebGL)
**Решение по стеку:** **остаёмся на R3F** — смена на Babylon/Unity Web не обоснована; текущий стек уже даёт industrial twin и STL.
Легенда: **Измерено** (код/сборка/тесты) · **Оценка** (экспертный вывод без GPU-профайлера браузера в этом отчёте).
---
## 1. Цель аудита
Отделить:
1. Что уже выглядит как оборудование.
2. Что всё ещё «игровое» или декоративное.
3. Что критично для доверия жюри за первые 10 секунд.
---
## 2. Текущая визуальная архитектура
| Компонент | Continuous `/` | Details `/details` |
| --------- | -------------- | ------------------ |
| Scene root | `SorterDigitalTwinContinuous` | `SorterDigitalTwin` |
| Items | `PhysicalPlaybackItem` / motion domain | `Item3D` + sim state |
| Conveyor | `Conveyor3D` + network layout | Аналогичные примитивы, другой wiring |
| Actuators | Gate/pusher анимации | State-driven actuators |
| Sensors | Overlay + measurement HUD | `SensorRig3D` / panels |
| Models | STL через `modelAssets` + fallbacks | То же семейство ассетов |
| Camera | Cinematic / demo camera path | Свободная/инженерная |
**Проблема parity:** два twin визуально расходятся — разные акценты освещения/композиции/детализации. Для жюри это снижает ощущение «одной реальной линии».
---
## 3. Чек-лист визуальных факторов
| Фактор | Статус | Комментарий | Тип |
| ------ | ------ | ----------- | --- |
| Геометрия / пропорции | Частично OK | Layout в мм через `physicalLayout` | Измерено |
| Масштаб сцены | OK | Единая физическая раскладка | Измерено |
| Камера / перспектива | OK на `/` | Cinematic playback | Измерено |
| Focal length / DoF | Минимально | DoF не форсируется (мешает чтению) | Оценка |
| Освещение | Среднее | Достаточно для читаемости; не studio HDRI | Оценка |
| Контактные тени | Ограничено | `shadows: false` в quality presets (perf) | Измерено |
| AO / post FX | Выкл. в presets | `effectsEnabled: false` | Измерено |
| Материалы PBR | Базовые | Шероховатость/металл упрощены | Оценка |
| Текстуры / загрязнения | Слабо | Нет сильного wear layer | Оценка |
| Края / bevel | Частично | STL + примитивы | Оценка |
| Движение ленты / ролики | OK с trade-off | Static/sparse rollers в perf-режимах | Измерено (ветка perf) |
| Приводы / задержки | Симулированы кинематикой | Не servo-physics | Измерено |
| Motion blur | Нет | Сознательно | Измерено |
| Anti-aliasing | По режиму | low/medium off; high/demo on | Измерено |
| Звук / вибрация | Нет | Не реализовано | Измерено |
| Заполнение накопителей | Упрощено | B receiver timing учтён в истории perf | Измерено (история) |
| CV overlay | Есть | RULE line + inspection | Измерено |
| Presentation declutter | Есть | Скрытие панелей в presentation | Измерено |
---
## 4. Режимы качества
Источник: `src/domain/qualityMode.ts` (**Измерено**).
| Mode | dprMax | AA | Shadows | maxItems | rollers | target FPS |
| ---- | -----: | -- | ------- | -------: | ------- | ---------: |
| low | 1 | нет | нет | 3 | none | 30 |
| medium | 1.25 | нет | нет | 5 | sparse | 30 |
| high | 1.5 | да | нет | 6 | full | 60 |
| demo | 1.5 | да | нет | 6 | full | 60 |
Автовыбор: по ширине viewport и опционально по recent FPS; `adaptQuality` понижает режим при просадке.
**Целевая демо:** стабильные 60 FPS при возможности, иначе стабильные 30 без рывков (**требование брифа**; фактический FPS на клиенте жюри — **не измерен в этом аудите на всех устройствах**).
---
## 5. Что выглядит убедительно
- Непрерывный путь товара от входа до B/C/D с подписями зон.
- STL-модели там, где ассет доступен; осознанные fallbacks для тяжёлых STL.
- Proof HUD и CV overlay связывают картинку с решением.
- Fault визуально останавливает поток (freeze).
- Presentation mode убирает engineering chrome.
---
## 6. Что снижает доверие («игровое»)
| Симптом | Почему заметно | Рекомендация |
| ------- | -------------- | ------------ |
| Разный вид `/` и `/details` | «Две разные игрушки» | Shared scene kit (Open) |
| Нет теней/AO | Плоские объекты | Осторожно включить в demo на мощных GPU клиентов |
| Pseudo-CV bbox | Идеальная геометрия | Оставить RULE + confidence честно |
| Отсутствие звука | Тихая «сцена» | Опциональный ambient loop (низкий приоритет) |
| Идеально ровное движение без контактов | Нет micro-collisions | Seeded jitter уже частично компенсирует |
---
## 7. Критичность для показа
| Приоритет | Находка | Действие |
| --------- | ------- | -------- |
| P0 | Proof + classification visible | Сделано |
| P0 | Presentation + hotkeys | Сделано |
| P1 | Twin visual unify | Open |
| P2 | Shadows/AO в demo-only | Open, perf-gated |
| P3 | Sound / wear textures | Backlog |
---
## 8. Вывод
Визуальный стек **достаточен**. Узкое место не «не тот движок», а **согласованность двух сцен** и **сдержанный shading ради FPS**. Для жюри важнее читаемый контур решения, чем ray-traced реализм. Следующий максимум ROI: унификация twin + актуальный production dist.