Перейти к содержанию

00 — ЧЕКЛИСТ РАСХОЖДЕНИЙ. Главный документ аудита симулятора «мир БВС»

Дата: 2026-09-16. Ветка feat/simulate-audit. Объект: simulate/ (2789 строк Python в src/geoscan_sim/, contracts/, fixtures/, 50 тестов). Источники: 12 отчётов аудиторов 01…12, ревью 90-review-evidence.md, 91-review-requirements.md, 92-review-completeness.md, реестр docs/90-final/02-requirements-registry.md (338 SIM-ID), BRD docs/90-final/01-business-requirements.md (BR-01…25, A-01…16, U-01…12).

Правила сведения статусов, применённые здесь: 1. Владелец вердикта по SIM-ID — тематический отчёт 01…09; отчёты 10…12 и ревью 90 — надзор. 2. При расхождении вердиктов берётся худший. Вердикт 90-review-evidence.md сильнее вердикта аудитора. 3. «ТРЕБОВАНИЕ НЕГОДНОЕ» — отдельная ось: ID попадает в корзину D и одновременно несёт свой фактический статус реализации. В счётчике статусов он занимает одну строку (как в отчётах-владельцах). 4. Всё, что проверено мной заново в этой сессии, помечено [проверено].


1. Сводка на одну страницу

1.1 Все 338 требований SIM-*

Статус Кол-во Доля Откуда
РЕАЛИЗОВАНО 5 1,5 % WORLD-02, WORLD-38, CAM-27, PLT-25, BIZ-28
ЧАСТИЧНО 57 16,9 % сумма отчётов 01–09
РАСХОЖДЕНИЕ 29 8,6 % 26 по отчётам + 3 понижения ревью (UAV-04/22/38)
НЕ РЕАЛИЗОВАНО 226 66,9 % сумма отчётов 01–09
НЕ ПРОВЕРЕНО 5 1,5 % PLT-19, UX-01, PLT-22-смежн. + понижения PLT-35/36
ТРЕБОВАНИЕ НЕГОДНОЕ 16 4,7 % 01×2, 03×3, 04×1, 05×1, 06×1, 07×3, 08×3, 09×2
Итого 338 100 % сумма сходится построчно

Сходимость по доменам (проверено grep -oE "SIM-[A-Z]+-[0-9]+" … | sort -u): BIZ 34, CAM 32, ENV 40, FIN 20, GEO 24, MIS 40, PLT 36, UAV 40, UX 34, WORLD 38 = 338 [проверено].

Из пяти «РЕАЛИЗОВАНО» четыре — документарные или вакуумные: WORLD-38 (оговорка про x86-64 в BRD), CAM-27 («осадки не моделируем» — строка в ограничениях), PLT-25 («checkpoint/resume не делаем»), BIZ-28 («не управляем бортами» — в коде нет MAVLink/сокетов). Содержательно реализовано кодом ровно одно требование из 338 — SIM-WORLD-02 (ENU через ECEF, geodesy/ecef_enu.py, 5 тестов PASS).

1.2 Вехи

Веха Требований РЕАЛИЗОВАНО % строго % с половинным зачётом ЧАСТИЧНО
M0 (всё MUST) 68 2 (WORLD-02, BIZ-28) 2,9 % 26,5 %
M1 157 0 0 % ≈7 % (оценка сверху)
M2 111 2 (CAM-27, PLT-25) 1,8 % 2,3 %
вне вех 2 0 BIZ-34 правомерно (COULD, V6 недостижим)

M0 после сведения худших вердиктов: РЕАЛИЗОВАНО 2 · ЧАСТИЧНО 32 · РАСХОЖДЕНИЕ 12 · НЕ РЕАЛИЗОВАНО 21 · НЕ ПРОВЕРЕНО 1. Отчёт 08 заявлял M0 = 11,8 % (8 из 68); ревью 90 сняло 6 из этих восьми (GEO-16, WORLD-04, UAV-22, UAV-26, CAM-01, PLT-17) — реальная цифра M0 = 2,9 %. Цифра M1 ≈ 1,3 % из отчёта 08 тоже не подтверждается: оба её основания (ENV-15, UAV-07) в собственных доменных отчётах стоят ЧАСТИЧНО. M1 = 0 %.

Отдельно: в реестре M0 посчитан как 67 — строка SIM-ENV-09 выпадает из любого табличного парсера из-за экранированных \|. Верное число — 68.

1.3 Зелёные метрики против их же содержания

Что предъявляется Факт [проверено] Что это значит на самом деле
pytest -q → 50 passed in 1.12s да 5 из 12 мутаций исходника (шаг позиции ×2, энергия не тратится, dt 0,1→0,25, срез 600→60 с, пустые assumptions_used) не убил ни один тест. Физика интегратора не удерживается ничем
sim validate --reference → 14 PASS, RC=0 да 10 из 14 эталонов тавтологичны: reference и actual — один и тот же вызов, отсюда delta = +0 ровно. Подмена endurance_max 40→55 в fleet.yaml даёт ref 55 / actual 55 / PASS
sim mutate → 12/12 detected, RC=0 да Честных детекций 10 из 12: m08 и m10 выдают ожидаемый код на немутированной базе s04. m04/m09 ссылаются на базы s06/s09, которых в fixtures/plans/ нет. --set игнорируется
Покрытие 79,4 % по трассеру отчёта 11 cli.py0 % (CLI и есть предмет сдачи), contracts/loader.py0 % (весь слой контрактов мёртв)
Детерминизм 10× один sha256 да Вырожден: ГПСЧ в коде нет, --seed 42--seed 999, --world totally-bogus ≡ дефолт, s01 и s07 (разные планы) дают один telemetry_sha256 a6706a37…

1.4 Ключевая находка — подтверждена

Тезис отчёта 12 ревью 90 подтвердило полностью (§5.2): валидатор — фасад над движком. [проверено] прямые рёбра: validator/invariants.py:5 → engine.integrator, validator/mutate.py:11 → mission.preflight, validator/references.py:9 → uav.energy, uav.kinematics, validator/identities.py:5 → camera.gsd. Транзитивное замыкание validator/ содержит 8 из 10 модулей движка; не разделяются только journal.writer и mission.import_plan (чистый I/O). Это блокер номер один. Пока он не снят, зелёные pytest/sim validate/sim mutate не являются доказательством ничего, и ни один следующий фикс нельзя принять.

1.5 Одна честная фраза о состоянии продукта

Сегодня это не симулятор, а детерминированный генератор прямолинейной телеметрии с набором формул-справочников: мир в прогоне не загружается, план не исполняется (одна фаза, один борт, жёсткий срез 600 с), факт покрытия копируется из плана, детекторы нарушений — восемь констант, подобранных под координаты 12 фикстур, а приёмочные метрики, которыми продукт себя проверяет, в большинстве сравнивают код сам с собой. Из 12 дословных фраз заказчика полностью не выполнена ни одна; фронтенда нет вовсе (0 файлов .ts/.js/.html [проверено]), API нет, реальных геоданных — 0 байт. К защите в текущем виде продукт непригоден.


2. Четыре корзины

Корзина A — чинить немедленно, иначе продукта нет

Порядок строк = порядок работ. Колонка «Заходов» — агенто-заходы (один заход = одна сфокусированная сессия с результатом размером одного PR). Расхождения с приоритизацией 92-review-completeness.md §5 помечены явно.

ID Что требовалось Что есть на самом деле Доказательство Что сделать Заходов
A0. SIM-BIZ-05, SIM-UAV-38, SIM-UAV-39, SIM-BIZ-10, SIM-BIZ-11, INH-05, INH-07 Валидатор не использует функции проверяемого кода (70-plan/01, «Принцип независимости»). V-1…V-14 — эталоны из первоисточников с колонкой отклонения; FAIL роняет CI Валидатора как сущности нет — есть фасад. 8/10 модулей движка внутри замыкания validator/. 10/14 эталонов считают ref и actual одним вызовом: V-1…V-4 читают одно поле fleet.yaml дважды, V-7…V-12 вызывают одну функцию. V-13 «геодезическая площадь» = side_m*side_m. V-3 не проверяет «при 19,4 м/с» — аргумент airspeed_ms мёртв validator/invariants.py:5, validator/mutate.py:11, validator/references.py:9, validator/identities.py:5,8 [проверено]; sim validate --reference → 10 строк с delta +0 [проверено]; подмена fleet.yaml 40→55 → ref 55/actual 55 PASS (отчёт 08 §2.6); мутации tan→sin, parachute_drift ×2, crosswind ×2, дерейтинг off → таблица остаётся refPASS (отчёт 11 §4) 1) reference в references.py — литерал первоисточника (40, 217, 180, 210, 7, 22, 136,4, 15,4, 18,2, 168, 30,0, 1,96) с полем source = пункт РЭ/строка YAML; 2) actual — только через публичный API движка; 3) новый ID + CI-проверка AST: пакет validator/ не имеет рёбер в engine/, mission/, uav/, camera/, env/; 4) вторая, независимая реализация геометрии/физики эталонов внутри validator/ — это и есть цена независимости; 5) V-13 — честная геодезическая площадь (Карней/сферический избыток); 6) снять из README и из речи на защите слова «независимая геометрия валидатора» 2–3
A1. SIM-BIZ-14, A-08, SIM-FIN-08 Негативный контроль: 12 мутантов детектируются, 0 ложных срабатываний на эталонном плане Детекция = «код найден в плоском множестве кодов плана». m08 и m10 дают expected-код на базе без мутации. Баз s06/s09 не существует. run_base_plan_check() смотрит только s01, хотя эталонных планов три: s04 даёт 4 ложных кода, s07 — один. run_mutant_matrix(set_name) игнорирует аргумент. В тесте V-9 стоит assert … or True mutate.py:37 (аргумент не используется), mutate.py:62-69 (только s01) ; контрфактный откат мутации: m08/m10 → «НЕ АТРИБУТИРОВАНО» (отчёт 11 §3.3); tests/test_references.py:35or True [проверено]; sim run s04 → 4 кода при metrics.violations = все нули [проверено] 1) детекция = expected ∈ codes(мутант) \ codes(его базы); 2) завести s06 и s09; 3) run_base_plan_check обходит все файлы fixtures/plans/, CI падает на любом коде; 4) удалить or True; 5) заставить --set работать или убрать флаг; 6) удалить легаси-манифест fixtures/mutants/manifest.yaml; 7) добавить антимутанты m25 (НФЗ западнее 37,63) и m26 (вышка в 500 м от координатной константы) — они обязаны краснеть сегодня 1–2
A2. Д-2 из 92 Каждая находка аудита закреплена падающим тестом CI зелёный на реализации со ~130 дефектами, то есть не ловит ни одного. Регресс после фиксов ловить будет нечем .github/workflows/simulate-ci.yml — 4 шага, все зелёные; 50 passed при 5 выживших мутациях исходника Перевести все дефекты корзин A и B в xfail-тесты до начала фиксов. Критерий приёмки любого захода: соответствующий defect-тест перестал быть xfail. Счётчик «зелёных» тестов приёмкой не является 1
A3. SIM-UAV-13, SIM-BIZ-20, SIM-ENV-11 РЭ-201 с. 30/36: запуск строго против ветра; запуск по ветру категорически запрещён. wind_direction_deg — откуда дует (INH-17) Логика инвертирована. TAKEOFF_INTO_WIND выдаётся при совпадении курса с направлением «откуда», т.е. на правильном старте. Запрещённый старт по ветру проходит молча. Инверсия закреплена в трёх артефактах: код, фикстура m04, реестр кодов preflight.py:122-126if abs(hd − wd) < 1.0 [проверено]; проба: heading 90 при ветре от 270 → []; contracts/error_codes.yaml:185-188 «Старт против ветра (NO-GO…)»; fixtures/mutants/m04_takeoff_into_wind.json Инвертировать условие (нарушение при отклонении > 90°), переименовать код в TAKEOFF_DOWNWIND, ввести warning TAKEOFF_HEADING_VS_WIND при отклонении > 30°, переделать m04, поправить message_ru. Приёмка — антимутант: «старт по ветру → violation; старт против ветра → 0 кодов» 1
A4. SIM-MIS-22/23/25, SIM-PLT-26/27, SIM-BIZ-32, SIM-GEO-10, SIM-FIN-11, BR-22 Журнал = манифест + события + телеметрия, append-only; манифест несёт хеши всех входов; телеметрия геопривязана В манифесте нет 9 из 14 required-полей своей же схемы (run_id, scenario_sha256, plan_sha256, run_config_sha256, telemetry_hz, clock_mode, import_fixups, started_at, exit_status). В телеметрии нет 4 из 4 required (t_sim_s, uav_id, lon, lat) — вместо них t_s, east_m, north_m. Потока событий нет вовсе (grep event src/ → 0 при 34 типах в схеме). Журнал открывается на "w" — перезапись, не append. jsonschema не установлен, схема не валидируется нигде Сверка required в отчётах 05 §3.2, 07 §3.1, 08 §2.6, 11 §3.6 — совпадает построчно; journal/writer.py:50,53 — режим "w"; contracts/loader.py покрытие 0 % 1) добавить jsonschema, валидировать оба артефакта при записи и в тесте; 2) lon/lat через EnuOrigin.from_enu + uav_id + t_sim_s в каждую запись; 3) plan_sha256/scenario_sha256/run_config_sha256/run_id/exit_status в манифест; 4) generated_at вынести из хэшируемой части (SIM-WORLD-36 это прямо требует); 5) поток events.jsonl; 6) повторный run_idRUN_ID_COLLISION, RC≠0 2–3
A5. SIM-WORLD-15/36/03, SIM-GEO-11/18, SIM-FIN-12, BR-03/07 Мир загружается до старта, результат определяется world_snapshot_id = sha256 входов, клиренс считается по рельефу runner.py мир не грузит вообще. world_snapshot_id — свободная строка CLI (--world totally-bogus-world-xyz даёт тот же хэш). 5 из 8 фикстур миров не загружаютсяKeyError: 'name': генератор пишет {world_fixture_version, kind, terrain{…}}, загрузчик ждёт {name, nx, ny, resolution_m, elevations}. Поле world_fixture манифеста мутантов не читает никто. HeightField.sample вне сетки молча экстраполирует клампом индексов cli.py:54, journal/writer.py:35; load_synthetic_world('ridge_80m_seed_42')KeyError('name') (5/5, отчёты 01 Р-7, 09, 11 §4.1, 12); terrain.py:157-160 — кламп индексов; hf.sample(100000.0, 45.0) → 147.36 без ошибки (отчёт 01 Р-11) 1) свести схему генератора и загрузчика, тест «каждый файл fixtures/worlds/*.json загружается»; 2) runner грузит мир, world_snapshot_id = sha256(входы‖origin‖шаг‖версии); 3) сэмплирование рельефа на шаге → terrain_z_m/alt_agl_m/clearance_m в телеметрию (поля уже в log_schema.json); 4) запрос вне bbox — ошибка, а не кламп; 5) тест «смена мира меняет хэш» 2–3
A6. SIM-UAV-01/15/35, SIM-MIS-06/16/19/20, BR-11, SIM-PLT-20 Автомат фаз prepare…landing с фактическими длительностями; мультиборт; единые модельные часы Интегратор летит по прямой одной фазой с постоянными курсом, высотой и скоростью; runner.py:54 режет любой вылет до 600 с; _first_sortie берёт первый вылет первой миссии. План s01 содержит 5 фаз и 1680 с — в манифесте "phase_durations_s": {"survey": 600.0}. s04 (3 борта, 5 вылетов) прогоняется как один вылет Gemini. В телеметрии нет uav_id. Энергия уходит в минус (−96,41 Вт·ч на 4000 с) без события runner.py:54 min(_sortie_duration(sortie), 600.0) [проверено]; integrator.py:80,101; отчёт 02 §3.1, §3.5; отчёт 05 §3.7 1) идти по геометрии галсов, автомат фаз по словарю плана; 2) снять min(…, 600.0) (или вынести в явный --max-duration с кодом RUN_TRUNCATED и RC≠0); 3) мультиборт хотя бы последовательный, uav_id в каждой записи; 4) порог энергорезерва + переход в return; 5) поток событий (34 типа уже в схеме) 2–3
A7. SIM-WORLD-21/28/30, SIM-GEO-11, SIM-UAV-11, SIM-CAM-10, SIM-ENV-39, BR-08 Детекция нарушений по геометрии: point-in-polygon для зон, рельеф и препятствия для клиренса, покрытие по футпринтам Восемь констант, подобранных под координаты фикстур: НФЗ = max(lon) > 37.63, вышка = окно ±0,001° вокруг 37.6495/55.772, клиренс = alt < 100.0, покрытие = interval ≥ 7.0 и spacing ≥ 200.0, оборот = gap < 105.0 между первыми двумя вылетами, старт = abs(hd−wd) < 1.0. В плане s01 нет ни одной зоныNFZ_VIOLATION порождается чистым порогом по долготе preflight.py:119,130,133,163,176,193 [проверено]; 11 проб отчёта 11 §3.4: ложные срабатывания (99 м AGL над плоскостью → CLEARANCE_VIOLATION; галс на lon 37,70 вне любой НФЗ → NFZ_VIOLATION; корректный AMSL-план → ALT_FRAME_MISMATCH) и ложные пропуски (шаг 199 м при футпринте 117 м; интервал 6,9 с; галс в 600 км от сцены; курс 272° при ветре 270°) Провести мир и зоны сценария в analyze_plan; клиренс — HeightField.sample + TowerObstacle.clearance_at + altitude_agl_min борта; покрытие — из payloads.yaml (футпринт и перекрытия); порог оборота — из battery.charge_time_min; AMSL пересчитывать через рельеф и геоид, а не клеймить ALT_FRAME_MISMATCH 2
A8. SIM-UAV-40, SIM-BIZ-27, SIM-CAM-29, SIM-MIS-28, INH-07, BR-17/21 planned / actual / delta_% по 4 метрикам; симулятор даёт факт, валидатор — расчёт; расхождение и есть выход продукта Отчёт план/факт выдаёт план за факт. coverage_fraction.actual — буквальная копия planned; energy_used_frac.actual = null; makespan_s.actual = 600.0 при planned = 1680 из-за среза; колонки delta_% нет. На s01 таблица читается как «покрытие подтверждено фактом 100 %» на прогоне, где не построено ни одного футпринта и не загружен мир runner.py:91-94 (actualmetrics.get("coverage_fraction")), runner.py:95-98, runner.py:54; вывод fact_report.json в отчётах 08 §2.6, 11 §3.6, 12 §3.8 1) actual — только из телеметрии/событий; при невозможности — null + status: NOT_COMPUTED; 2) колонка delta_%; 3) энергия — из энергомодели; 4) ГПСЧ с потребителем seed либо явное объявление «стохастики нет, детерминизм тривиален» в манифесте. Копирование планового значения в actual объявить дефектом класса fatal 1–2
A9. SIM-MIS-35, SIM-MIS-01, SIM-FIN-08, BR-01/BR-18 (добавлено сверх §5 отчёта 92) Фатальная ошибка → прогон не стартует; нарушения → RC ≠ 0; план без сценария → SCENARIO_MISSING; версия схемы проверяется sim run s04 при 4 нарушениях → RC=0; sim run m06_ir_on_gemini.json (fatal по §1.5) → RC=0, журнал записан. План без scenario_id → RC=0, scenario_id: null. План с schema_version: 99 и вовсе без поля проходит импорт cli.py:55-62 не анализирует preflight_codes [проверено: sim run s04 → RC=0]; отчёт 05 §2 (MIS-35), отчёт 08 (BR-01), отчёт 09 (FIN-08) Ввести реестр кодов выхода (fatal-импорт / нарушения / чисто), SCENARIO_MISSING, PLAN_SCHEMA_VERSION_UNSUPPORTED, подключить contracts/loader.py. Почему в A, а не в B: пока sim run возвращает 0 на любом нарушении, продуктовый гейт мёртв, и приёмка всех остальных фиксов держится только на pytest 1

Приёмка корзины A целиком: sim run s01 даёт факт 1680 ± 5 % с разбивкой по фазам; s01/s04/s07 — 0 ложных кодов; мутанты 12/12 с контрфактом и 2 антимутанта краснеют до фикса детекции; журнал проходит log_schema.json; смена seed, мира или плана меняет telemetry_sha256; ни один reference не вычисляется вызовом продуктового кода (проверка AST в CI). Итого корзина A: 13–18 заходов, 2 обязательные итерации ревью (после A2 и после A9).


Корзина B — чинить до защиты

ID Что требовалось Что есть на самом деле Доказательство Что сделать Заходов
B1. все 34 SIM-UX, SIM-PLT-01/02, BR-23, U-05, п. 4 ТЗ 3D-интерфейс: сцена, 4 вида камеры, таймлайн событий, панель телеметрии, экран покрытия Фронтенда нет ни в каком виде: 0 файлов .ts/.tsx/.js/.html/.css, нет package.json, нет совпадений по deck.gl/maplibre/three/webgl [проверено]. HTTP-слоя нет: зависимости — click, numpy, pyyaml, pytest Отчёт 07 §0 и §3 (15 бэкендных предпосылок: реализовано 0, частично 3, расхождение 3, не реализовано 7) Минимальный просмотрщик журнала (пролёт по telemetry.jsonl, таймлайн из событий) + минимальный HTTP (/healthz, POST /plans, GET /runs/{id}). Не редактор сценариев. Стартует сразу после A4 (lon/lat), не после всей корзины A 3–4
B2. SIM-MIS-02/08, SIM-BIZ-01, SIM-PLT-08, BR-02, п. 2 ТЗ Приём плана в трёх форматах: наша схема, GeoJSON RFC 7946, KML OGC 2.2 Принимается только внутренний JSON: grep -rniE "kml\|geojson\|kmz\|xml" src/ tests/ tools/ → 0 [проверено]. Стыковки двух половин продукта не существует Отчёт 05 §3.1, отчёт 08 (BIZ-01, BR-02) Импорт KML/GeoJSON + 15 проверок импорта §5.2 + машиночитаемые ошибки {code, severity, path, message} вместо трейсбека + сквозной тест «реальный KML планировщика → sim run → числа обратно» (дыра Д-3 ревью 92) 2–3
B3. SIM-ENV-10/15/23/24/25, SIM-WORLD-31, SIM-UAV-08, SIM-BIZ-16 Среда действует на борт: ветер и температура из сценария, wind_max-отсекатель, LOS по рельефу, реакция на потерю связи В sim run ветер всегда 0, температура всегда +20 °C — runner.py:55-62 их не передаёт, дерейтинг в прогоне не срабатывает никогда. wind_max не читается вовсе. LOS = круг радиодальности, terrain_blocks никто не выставляет. link_up падает на 500-й секунде — событие не пишется, failsafe_triggered не читает никто, t_out_of_link_max_s не считается Отчёт 04 §1 (таблица четырёх воздействий), §3.4, §3.5, §3.10; env/link.py:36-39; integrator.py:98 Погода в run_config/сценарии → IntegratorConfig; WIND_EXCEEDS_FLEET_MAX; дерейтинг для всех бортов + TEMP_OUT_OF_RANGE; LOS профилем по рельефу с зазором 0,6·F₁; t_out_of_link_max_s в отчёт; предикат продолжения хотя бы по каналу связи 3
B4. SIM-CAM-03/10/18/22/24/30, BR-14/15, U-11 «Сухой» геометрический кадр — дефолт headless: футпринт, GSD, покрытие, сайдкар Ни одного кадра ни в одном из трёх режимов. Вся тема — 32 строки camera/gsd.py. PayloadSpec не парсит sensor_height_mm/image_height_px, поэтому Dh вычислить нечем. GSD не считается для главной камеры 201 sony_rx1rm2 (нет image_width_px) — а на ней построены V-5/V-6 и расчёт объёма §4.4. Контракта кадра нет даже как схемы Отчёт 03 §1 (контрольная таблица GSD), §3.1, §3.4, §3.5; payload_spec('geoscan_801_thermal')['sensor_height_mm']KeyError Футпринт, frame_record в log_schema.json, сайдкар, сверка числа кадров с plan.phases[].photos, карта GSD + GSD_OUT_OF_SPEC, altitude_for_gsd, полный парсинг PayloadSpec 2–3
B5. SIM-FIN-09/10, SIM-UAV-23, SIM-BIZ-26 Один реестр кодов, один сквозной реестр допущений, ТТХ только из YAML contracts/loader.py — 0 % покрытия, не импортируется никем. 33 литерала кодов в preflight.py; 4 легаси-кода вне реестра; 29 из 42 кодов не эмитируются. Два реестра допущений (27 ASSUMP-* против 4 A-*), в манифест уходит меньший, G_STD вне всех нумераций. 801 роняет прогон ValueError: No energy_wh Отчёт 09 §1 и §2 (FIN-09, FIN-10); отчёт 12 §3.12; отчёт 02 §3.6, §3.12 Подключить loader, коды и допущения — только из реестров, тест «множество выдаваемых кодов ⊆ реестр и наоборот», удалить дубли, 801 — энергоканал по времени 1–2
B6. SIM-BIZ-02/09, SIM-MIS-33, SIM-PLT-01, SIM-FIN-03/16, BR-19/25, Д-5 Стенд: docker compose up офлайн, sim batch, 6 артефактов документации, трёхзначный вердикт Ни Dockerfile, ни compose, ни подкоманды batch [проверено: git ls-files \| grep -i docker → пусто]. На них висят 3 M0/M1-требования и 2 критерия приёмки. Вердикта NO-GO/UNRESOLVED/NO-FINDINGS нет, как и всех трёх его предусловий (fidelity_class, layer_completeness, V3). Документации 3 из 6 Отчёт 06 §1, отчёт 08 §3.12, отчёт 09 (FIN-03, FIN-16), отчёт 11 §5.10 Dockerfile + compose, sim batch, прогон на чистой машине без сети, вердикт (по правилу §7.2 он сегодня обязан быть всегда UNRESOLVED — это надо сказать вслух, а не показывать зелёный NO-FINDINGS), добить 6 артефактов 2–3

Итого корзина B: 13–18 заходов, 2 итерации ревью (после B2+B3 и предзащитная полная).


Корзина C — записать в известные ограничения и жить

Каждая строка — запись в перечне ограничений с номером допущения, а не молчание.

Область ID Почему в C
Реальные геоданные GLO-30 / WorldCover / ArcticDEM SIM-GEO-01/02/03/04/13/15, SIM-FIN-07/18, SIM-GEO-24 Спайк 0.1 заблокирован (docs/91-implementation/geodata-blocker.md, fixtures/mirror/manifest.json"status":"blocked"). Защита на синтетике с честным манифестом (CRS, дата, sha256) + слот загрузки настоящей ЦМР. README сегодня обещает «реальную местность в настоящих координатах» — фразу надо понизить, а не сдавать
Зона Френеля, рефракция k=4/3, модель потерь пакетов SIM-WORLD-31 (часть), SIM-ENV-23 (часть) Сверх ридж-кейса из B3 — цена/ценность не оправдана до защиты
Полный каталог W-01…W-24 и ~30 буквальных кодов РЭ SIM-ENV-28/40 24 сценария и кириллические коды РЭ — объём отдельной волны
Мультиспектр TIFF, EXIF/XMP, тени по солнцу, смаз, обледенение SIM-CAM-13/16/19/20/26, SIM-ENV-14 M2, вне сдачи
Наблюдаемость Prometheus/Grafana, SSE/live SIM-PLT-15/29/30/31, SIM-UX-30 До деплоя беспредметна; SSE осознанно понижен в M2 самим реестром
Кросс-платформенная бит-идентичность, «через 7 суток» SIM-WORLD-38, SIM-GEO-18 (часть) Объявлено в BRD §11.2; второй машины и ARM в контуре нет
100 сценариев за ночь, ≥4 параллельных прогона, checkpoint/resume SIM-PLT-22/25, SIM-BIZ-07 M2, честно объявлено «не делаем»
Полное дерево contingency (12 действий), P1–P6 сверх link-ветки SIM-ENV-37/38 (часть) Ветка связи закрывается в B3; остальные 11 действий — после защиты
Потоковая запись телеметрии и бюджет памяти SIM-PLT-24, SIM-MIS-25 (часть объёма) Измерено 21,55 МБ на 180 мин при 11 полях — бюджет ≤ 20 МБ ломается; см. корзину D
Опасные сближения, очередь на площадке, разделение по высотам SIM-UAV-36/37, SIM-MIS-38/39/40 M2; недостижимо до мультиборта из A6

Объём: 1 заход (таблица допущений, не код).


Корзина D — требование неверно, чинить требование, а не код

16 ID со статусом ТРЕБОВАНИЕ НЕГОДНОЕ + 6 недомаркированных кандидатов из 91 §1.2. Один PR по docs/.

ID Что требовалось Что не так с требованием Доказательство Что сделать
SIM-GEO-17, SIM-WORLD-01 Манифест снапшота / перечень 8 слоёв Критерий M0-MUST выражен через API world/{id}, который сам отнесён к M2 (SIM-PLT-03/05). Неисполним по построению Реестр стр. 62, 79 против стр. 316, 318 Перецелить на артефакт сборки мира (файл world_manifest.json); добавить CRS и дату выгрузки в контракт
SIM-BIZ-05 «0 рёбер импорта из simulate/ в coverage/, routing/» Тривиально истинно — планировщика на Python в репозитории нет; не описывает реальный канал заражения (валидатор → движок). Самая дорогая дыра постановки Отчёт 12 §5.1, ревью 91 §1 Новый ID: «пакет validator/ не импортирует engine/, mission/, uav/, camera/, env/; проверка AST-графа в CI». Уходит в A0
SIM-UAV-38 Эталоны одной командой, RC≠0 при FAIL Не запрещает вычислять reference продуктовым кодом — реализация воспользовалась буквально. «История прогонов доступна» без носителя и срока непроверяема Отчёт 11 §6.5, ревью 91 §1 Дописать: «reference — литерал первоисточника с указанием пункта; вычисление reference вызовом движка запрещено (AST в CI)». «Историю» специфицировать или снять
SIM-BIZ-10 9 аналитических тождеств V1 Неатомарно (9 проверок — один вердикт, реализовано 5); допуск round-trip 0,01 м в реестре против 0,05 м в BRD §7.1; там же «площадь в UTM» вопреки запрету UTM в WORLD-02/04 Отчёт 08 §4.1, отчёт 11 §6.1 Разбить на V1-01…V1-09 с ID, один допуск (0,01 м), проекцию заменить на ENU/геодезическую
SIM-BIZ-11 «Инварианты V2 держатся» 6–7 разнородных инвариантов под одним MUST; «независимость от зоны UTM» противоречит WORLD-04; «энергобаланс ≤ 0,1 %» не определяет состав баланса — рискует стать тождеством Отчёт 12 §5.4 Разбить на 6 ID; определить баланс: Σ P·Δt по фазам против ΔE с ветром и набором
SIM-UAV-02 Погрешность ≤ 5 % / ≤ 10 % Циркулярен: эталоны §9.2, на которые ссылается, сами построены из fleet.yaml или из формул. V6 объявлен недостижимым Ревью 91 §1 Убрать из M0. Вместо точности — «дельта печатается и раскладывается на компоненты»; погрешность против независимых точек — M1
SIM-UAV-22 Калибровка: Gemini 40 ± 2 мин Приёмка сверяет якорь с ним же: подмена 40→55 даёт ref 55/actual 55 PASS Отчёт 10, отчёт 08 §2.6 «Модель воспроизводит не участвующие в калибровке точки: survey_area_per_flight [7,22], range_max 210 км» — заметим, дальность сегодня даёт 147 км, честный критерий покраснел бы
SIM-UAV-06 vs SIM-FIN-10 ≥ 9 записей A-01…A-09 / сквозные ASSUMP-* Два MUST M0 несовместимы; код закономерно родил два реестра и выбрал меньший Отчёт 09 (UAV-06) Один реестр contracts/assumptions.yaml, старые A-xx — алиасы; число «≥ 9» убрать
SIM-UAV-07, SIM-UAV-27, SIM-UAV-35, SIM-PLT-21, SIM-PLT-23, SIM-MIS-25 Числовые противоречия реестра и доменных документов: 28/30 мин; ≤3 м/9,0 м и ссылка на несуществующий s06; 120 с на 8 ядрах / 3600 с на ядре; ≥20× / ≤60 с на борт-час (+два MUST-владельца одного бюджета); 20 ГБ / 100 ГБ; 5 Гц-54 000-10 МБ / 10 Гц-108 000-20 МБ Ревью 91 §1 и §7.1 (6 доказанных числовых противоречий) Объявить реестр 90-final/02 единственным источником правды, §9-таблицы доменов заменить ссылками; для MIS-25 пересчитать бюджет под 31 поле (измерено 21,55 МБ уже на 11 полях)
SIM-MIS-28 Diff имён полей с валидатором пуст M0-MUST завязан на артефакт вне поставки; конфликтует с SIM-BIZ-27 ровно там, где у симулятора нет способа измерить покрытие — реализация разрешила конфликт копированием плана в факт Отчёт 12 §5.2 Разделить: «имена из машиночитаемого словаря 70-plan/01» (M0) + «кросс-сверка с валидатором» (M1, вместе с BIZ-12)
SIM-CAM-06, SIM-CAM-23, SIM-CAM-24 lever arm; объём ≤1,3×; «сухой» кадр Вакуумное отрицание без сайдкара; две живые редакции одного ID; MUST/M1 принимается отношением к необязательному M2-рендеру. Плюс коллизия ID «А-5» в четырёх реестрах Отчёт 03 §4 Переформулировать позитивно; оставить редакцию реестра; абсолютный порог «153 000 сухих кадров ≤ N мин на ядре»; развести коллизию ID
SIM-UX-03, SIM-UX-14, SIM-UX-24 Рендер = live; имена полей панели; 30 FPS Сравнение потока с самим собой (live в M1 нет по решению того же реестра); имена voltage_v/endurance_left_s/energy_left_wh против замороженного log_schema.json при требовании MIS-28 «diff пуст»; требование само объявляет себя неизмеримым и тут же задаёт замер Отчёт 07 §4 Переписать на «плеер воспроизводит позиции из telemetry.jsonl ≤ 0,1 м»; один словарь полей = log_schema.json; UX-24 — в §11 «вне объёма»
SIM-ENV-11 Курс старта — функция ветра Реестр сам пишет «дублирует SIM-UAV-13, отдельная реализация не нужна» — ID без предмета; опасен тем, что инвертированная реализация «закрыла» оба Отчёт 04 (ENV-11) Превратить в ссылку без статуса; текст «старт против ветра — NO-GO» исправить по РЭ-201 (кодовая половина — в A3)
SIM-ENV-22 (M2) vs ENV-23/24/25 (M1) Четыре канала связи Понятие канала требуется позже его свойств Отчёт 04 §3.12 Выровнять вехи
SIM-FIN-06, SIM-FIN-19 Демонстрация как артефакт; приоритет интерактивных прогонов Склейка 4 артефактов под одним MUST, из них полигон зависит от заблокированного FIN-07; критерий без числа + половина-признание, дублирующая BRD §11.5 Отчёт 09 (FIN-06, FIN-19) Разнести на 3–4 ID; либо число, либо в §11
A-02, A-09 (критерии приёмки BRD) «10 повторов → один sha256 журнала»; «≥1 нарушение, невидимое валидатору» Журнал по MIS-22 включает манифест с generated_at → невыполним по построению (10 манифестов = 10 sha256). A-09 опирается на два несуществующих артефакта Отчёт 08 §4, ревью 91 §1 «sha256 телеметрии и fact_report идентичны; манифест — после исключения generated_at». A-09 — цель M1 с явными предусловиями
SIM-BIZ-34 Калибровка по реальной телеметрии (V6) ОТКЛОНЕНО как негодное (ревью 91 §1, прав отчёт 12): условное COULD вне вех с честной ссылкой на недостижимость — образец требования, которое не будет сделано Пометить «условное; в проценты готовности не входит». Из реестра не удалять
Кандидаты, не поднятые аудиторами SIM-WORLD-06, SIM-CAM-03, SIM-GEO-09 vs MIS-03, SIM-MIS-17 vs MIS-16, SIM-PLT-26 vs PLT-28, A-14/SIM-BIZ-02 «Нижняя граница» против «центрального значения» (два живых противоположных текста); допуск 0,1 % недостижим против собственной таблицы, где Bx посчитан как By/2; enum фреймов задан трижды тремя способами, код ввёл четвёртый (RELATIVE); dt/2 требуется, но dt не параметр; engine_version обязателен и определён только как тег docker-образа; критерии над несуществующими каталогами Ревью 91 §1.2 Поднять до «негодных» и починить вместе с остальными

Объём: 1–2 захода + 1 итерация ревью (сверка реестра с доменами скриптом).


3. Порядок работ и зависимости

Первым — не код продукта, а оракулы. Порядок не произволен: каждая следующая волна физически не может быть принята без предыдущей.

Волна Что Почему именно здесь Блокирует
1 A0 (эталоны-литералы + AST-тест независимости), A1 (контрфакт мутантов, s06/s09, or True, --set), A2 (дефекты → xfail-тесты) Метод проекта — «валидатор раньше продукта» (70-plan/01). Пока reference вычисляется движком, а «детекция» засчитывается по коду, который был и до мутации, ни один следующий фикс недоказуем: он будет принят той же тавтологией, которая пропустила текущие дефекты всё остальное
2 A3 (инверсия ветра) Дешёво (строки), но до неё матрица мутантов и V5 недействительны: m04 «зелёный» именно потому, что ловит правильный план. Пока правило инвертировано, любой фикс детекции будет подгоняться под ложный ответ A7, B3
3 A4 (журнал по контракту + геопривязка) Без lon/lat, uav_id, plan_sha256 и потока событий нечего показывать и нечего воспроизводить. Точка разветвления: сразу после A4 можно вести B1 параллельно — просмотрщику нужен геопривязанный журнал, а не готовая физика A5, A6, A8, B1, B4
4 A5 (мир в прогоне) Все проверки клиренса, НФЗ и LOS без мира остаются константами. A7 без A5 невозможен технически: сэмплировать нечего A6, A7, B3
5 A6 (полёт по плану: фазы, снятие среза 600 с, мультиборт, события) «Облёт полётного задания» — суть продукта. Самая тяжёлая работа; делается после A5, потому что траектория должна сэмплировать рельеф A8, B3, B4
6 A7 (детекция по геометрии), A9 (RC≠0, SCENARIO_MISSING, версия схемы) A7 требует и мира (A5), и правильного правила ветра (A3), и честных мутантов (A1). A9 можно делать раньше, но приёмка A7 без него неполна: нарушения не роняют прогон B2
7 A8 (честный fact_report с delta_%) Последний в A: actual можно считать только когда борт действительно летит по плану (A6) и мир участвует (A5). Раньше — снова получится план, напечатанный дважды B1 (экран сравнения), B6 (вердикт)
8 Обязательное ревью корзины A + пере-замер перфа (дыра Д-6 ревью 92) Все перф-числа (0,80 с/борт-час, запас ×75) сняты на прямолинейном стабе без рельефа, кадров, событий и второго борта. После A5–A6 бюджет SIM-MIS-34/SIM-PLT-21 может быть провален молча — замер обязан войти в приёмку A B-волны
9 B1 (просмотрщик + минимальный HTTP) — стартует с волны 3, B2 (KML/GeoJSON), B3 (среда в прогоне) B1 — самый рискованный (34 SIM-UX с нуля) и оценивается жюри по п. 4 и п. 8 ТЗ; вести параллельно. B3 после A6 — иначе воздействию не на что действовать B4, B6
10 B4 (сухой кадр), B5 (оживить контракты), B6 (стенд, батч, вердикт, документация) B4 после A4 (контракт кадра идёт в ту же схему журнала). B6 последним: вердикт опирается на всё предыдущее
11 D (один PR по docs/) — можно вести с волны 1 параллельно, C (таблица ограничений) — перед защитой D не зависит от кода, но должен опередить приёмку: пока реестр и домены противоречат друг другу шестью числами, исполнитель будет чинить под неверный эталон приёмка A/B

Три жёсткие зависимости, которые нельзя нарушить: 1. A7 (геометрическая детекция) невозможен без A5 (мир в прогоне) — сэмплировать нечего. 2. A8 (честный факт) бессмысленен без A6 (полёт по плану) — actual будет снова копией плана. 3. B1 (фронт) невозможен без A4 (lon/lat в телеметрии) — борт некуда положить на карту.

Дисциплинарное условие (риск Р-1, «Goodhart повторится»): A0 и A1 делает отдельный агент, не тот, кто потом чинит продукт. Ранние признаки рецидива, которые ревью обязано проверять руками в каждой волне: дельты эталонов снова ровно +0; контрфакт мутанта зелёный на базе; detail мутанта многокодовый; правка fleet.yaml не меняет числа прогона.

Объём

Корзина Заходов Итераций ревью
A (A0–A9) 13–18 2 (после A2; после A9 — повторный срез по образцу отчётов 11/12)
B (B1–B6) 13–18 2 (после B2+B3; предзащитный полный)
C 1
D 1–2 1 (сверка реестра с доменами скриптом)
Итого 28–39 5–7

Расхождение с 92-review-completeness.md §6 (там 24–33 захода, 5–6 ревью) названо честно: я добавил A2 (defect-тесты как отдельная работа), A9 (коды выхода и контракт входа) и пере-замер перфа в приёмку A. При параллелизации (B1 с волны 3, D с волны 1) — 5–6 волн; критический путь A0 → A2 → A4 → A5 → A6 → A8, а не «вся A → вся B».

Приёмка каждого захода: соответствующий defect-тест из A2 перестал быть xfail. Счётчик зелёных тестов приёмкой не является — это главный урок этого аудита.


4. Статусы, понижённые ревьюером

Это важнее прочего: таблица показывает, где отчётам аудиторов нельзя доверять на слово. Источник — 90-review-evidence.md §1, §2, §4.2, §6.

4.1 Понижения по существу (перепроверка опровергла вердикт)

ID Аудитор сказал Где Перепроверка ревью Итоговый статус Почему
SIM-UAV-04 РЕАЛИЗОВАНО 02 нет РАСХОЖДЕНИЕ Детерминизм получен отсутствием стохастики, а не управлением ею: --seed 42--seed 777 (a6706a37…), ГПСЧ в src/ не используется
SIM-UAV-22 РЕАЛИЗОВАНО 02, 08 §2.5 нет РАСХОЖДЕНИЕ (+ D) energy.py:45-54 возвращает spec["endurance_max"] — круговая сверка fleet.yaml с самим собой; V-1…V-4 delta +0. Отчёт 10 был прав, отчёт 02 промахнулся
SIM-UAV-38 РЕАЛИЗОВАНО 02 нет по смыслу РАСХОЖДЕНИЕ Буква выполнена (одна команда, RC≠0 при FAIL), содержание — нет: 10/14 эталонов тавтологичны. Статус противоречит телу собственного доказательства отчёта 02
SIM-GEO-16 РЕАЛИЗОВАНО 08 §2.5 нет ЧАСТИЧНО (как в 01) В §2.5 нет цитаты вывода socket-hook, только фраза «завершился успешно»; критерий требует docker compose up, которого не существует
SIM-WORLD-04 РЕАЛИЗОВАНО (вакуумно) 08 §2.5 нет как полный зачёт РАСХОЖДЕНИЕ (как в 01) Grep UTM пуст — но проверка «площадь в проекции ≤ 0,1 %» подменена round-trip-замыканием ENU→WGS84→ENU, origin теста — экватор, а не демо-полигон
SIM-CAM-01 РЕАЛИЗОВАНО 08 §2.5 частично ЧАСТИЧНО (как в 03) Геометрия из payloads.yaml читается, но числа, заменяющие футпринт, захардкожены (interval ≥ 7.0, spacing ≥ 200.0, payload_spec("sony_rx1rm2") в energy.py)
SIM-PLT-17 РЕАЛИЗОВАНО 08 §2.5 завышено ЧАСТИЧНО (как в 06) Офлайн доказан, но критерий «docker compose up проходит регрессию» не исполнен
SIM-UAV-26 РЕАЛИЗОВАНО 08 §2.5 да по факту, нет по доказательству ЧАСТИЧНО (как в 02) wind_triangle и раздельные heading/track есть; ЛЗП как объекта нет, xtrack не считается — вторая половина требования не закрыта
SIM-PLT-35 РЕАЛИЗОВАНО (вакуумно) 06 только grep НЕ ПРОВЕРЕНО Нет negative-теста CLI; проверка тождественно истинна, потому что API отсутствует, и останется истинной после нарушения границы
SIM-PLT-36 РЕАЛИЗОВАНО (вакуумно) 06 только git grep НЕ ПРОВЕРЕНО Секретов нет, потому что секретов у симулятора пока нет вовсе
SIM-CAM-17 РЕАЛИЗОВАНО 10 опровергнуто ЧАСТИЧНО (как в 03) Приёмка сформулирована через «запрос ИК-кадра», которого не существует; проверяется план, а не съёмка. Отчёт 10 переоценил (ревью 91 §1.1)
SIM-WORLD-02, BR-06 РЕАЛИЗОВАНО 08 §2.5 / §2.2 содержание да РЕАЛИЗОВАНО (сохранено) В 08 вывод pytest не приложен, но в 01 он есть и координатор перепроверил лично — единственные зачёты, устоявшие полностью

Счёт: из 17 выборочно перепроверенных вердиктов «РЕАЛИЗОВАНО» подтверждено 9, опровергнуто или завышено 5, документарно/вакуумно с оговоркой 3. Из восьми «РЕАЛИЗОВАНО» M0-сводки отчёта 08 устояли два.

4.2 Один ID — несколько статусов (ломает любой автоматический rollup)

ID Отчёт A Отчёт B Принято здесь
SIM-CAM-01 03 — ЧАСТИЧНО 08 §2.5 — РЕАЛИЗОВАНО ЧАСТИЧНО
SIM-GEO-16 01 — ЧАСТИЧНО 08 §2.5 — РЕАЛИЗОВАНО ЧАСТИЧНО
SIM-PLT-17 06 — ЧАСТИЧНО 08 §2.5 — РЕАЛИЗОВАНО ЧАСТИЧНО
SIM-UAV-38 02 — РЕАЛИЗОВАНО 11, 12 — РАСХОЖДЕНИЕ РАСХОЖДЕНИЕ
SIM-UAV-22 02 — РЕАЛИЗОВАНО 10 — ТРЕБОВАНИЕ НЕГОДНОЕ РАСХОЖДЕНИЕ + корзина D
SIM-CAM-17 03 — ЧАСТИЧНО 10 — РЕАЛИЗОВАНО ЧАСТИЧНО
SIM-BIZ-34 08 — НЕГОДНОЕ 12 — «образец требования» Не негодное; в проценты готовности не входит

4.3 Дефекты доказательной базы самого аудита

Тяжесть Проблема Где Что с этим делать
A M0-сводка §2.5 завышает «РЕАЛИЗОВАНО» без прогонов: 8 строк без вывода команд, 6 из них сняты 08-business-and-milestones.md Переносить только статусы с блоком вывода из 01/02/06/10/11. Цифра M0 для защиты — 2,9 %, не 11,8 %
A Мета-утверждение «отчётам можно верить» шире фактической выборки: перепроверялись в основном красные факты, а не 338 зелёных/жёлтых статусов 92-review-completeness.md §1.2 Ограничить формулировку: «дефекты, перечисленные в 11–12, воспроизводимы»
B 08 §1.1 заявляет 90 позиций, в таблицах §2.1–2.4 — 87–88; вехи M0/M1/M2 не имеют отдельных строк вердикта 08 Добавить 3 строки вех или исправить Σ
B SIM-UAV-28: \| в ячейке ломает markdown-таблицу — вердикт «теряется» при автоматическом разборе 02 Экранировать; та же болезнь у SIM-ENV-09 в реестре (из-за неё M0 считался как 67)
C Собственный % покрытия (79,4 %) измерен самописным трассером, coverage в venv нет 11 §3.9 Доверять качественно: cli.py 0 %, contracts/loader.py 0 % — это воспроизводится

Что из аудита воспроизводимо и на что можно опираться: отчёты 11-test-run-evidence.md и 12-validator-independence.md перепроверены координатором полностью и подтверждены. Именно они — рабочий каталог дефектов. Отчёты 01…09 надёжны в «красной» части и завышены в «зелёной».


5. Сверка с дословной постановкой заказчика

Источник фраз — simulate/docs/00-brief/02-vision-and-business.md, 00-brief/03-primary-sources-digest.md, BRD. Статус — по факту кода (92-review-completeness.md §2, перепроверено).

Фраза заказчика Статус по факту кода ID и доказательство
«Карта местности и топосъёмка» НЕ РЕАЛИЗОВАНО — реальных геоданных 0 байт (fixtures/mirror/manifest.jsonstatus: blocked); синтетика есть, но прогон её не читает, а 5 из 8 фикстур миров не открываются (KeyError: 'name') SIM-GEO-01/24, SIM-WORLD-15; корзины A5, C
«3D-мир с настоящими координатами» НЕ РЕАЛИЗОВАНО — телеметрия в локальном ENU (east_m/north_m) без lon/lat; EnuOrigin в конвейер прогона не включён; 3D-сцены нет. README обещает это первой строкой SIM-GEO-10, SIM-WORLD-03; корзины A4, B1
«Зоны (НФЗ, разрешённое воздушное пространство)» СУРРОГАТ — НФЗ = литерал max(lon) > 37.63, геометрия зон не участвует; корректная модель зоны в nfz_corner_seed_42.json не читается SIM-WORLD-21/28/30, SIM-GEO-11; корзина A7
«Несколько типов БВС со своими ТТХ» ЧАСТИЧНОfleet.yaml/payloads.yaml читаются, совместимость нагрузок работает (m06); но 801 роняет прогон (ValueError: No energy_wh), мультиборта нет, ветвлений по type нет, правка airspeed_cruise не меняет длительность вылета SIM-UAV-05/09/23/35, SIM-BIZ-30; корзины A6, B5
«Камера и получение изображений» НЕ РЕАЛИЗОВАНО — ни кадра ни в одном из трёх режимов, ни футпринта, ни сайдкара; считается один скаляр GSD, и тот падает на главной камере 201 sony_rx1rm2 SIM-CAM-11/24/03/23, BR-15; корзина B4
«Облёт полётного задания» НЕ РЕАЛИЗОВАНО — интегратор летит одной фазой по прямой с постоянным курсом, геометрия плана игнорируется, вылет обрезан 600 с (факт 600 против плана 1680) SIM-UAV-15/02, SIM-MIS-06; корзина A6
«Молния» НЕ РЕАЛИЗОВАНО — 0 строк (grep гроза/storm/lightning → 0) SIM-ENV-18…21; корзина C
«Ветер» ЧАСТИЧНО (0,5) — формулы есть и оттестированы (wind_triangle, степенной профиль), но в sim run ветер всегда 0: runner.py погоду в IntegratorConfig не передаёт SIM-ENV-10/15; корзина B3
«Снег / осадки» НЕ РЕАЛИЗОВАНО — 0 строк SIM-ENV-12…14; корзина C
«Недоступность сети» ВЫРОЖДЕННОlink_up=False по кругу радиодальности случается (на 500-й секунде s01), но никто не реагирует: события нет, failsafe не читается, t_out_of_link_max_s не выдаётся. Наземная сеть (ENV-27) — 0 SIM-ENV-23/24/25/27; корзина B3
«Борт обрабатывает воздействие и продолжает маршрут» НЕ РЕАЛИЗОВАНО — дерево contingency: 0 из 12 действий; предикат продолжения P1–P6 отсутствует. Демонстрацию «справился» подкрепить нечем SIM-ENV-37/38; корзины B3, C
«Фронт и бэкенд на 3D-технологиях» НЕ РЕАЛИЗОВАНО — 0 файлов фронтенда, 0 HTTP; бэкенд не готов фронт питать (нет lon/lat, событий, кадров, сцены) все 34 SIM-UX, SIM-PLT-01/02; корзины A4, B1

Счёт: полностью выполнено 0 из 12 · частично 3 · не выполнено 9.

Демонстрируемых заказчику вещей сегодня две — детерминированный headless-прогон и таблица тождеств V1 — и обе не входят в его список.

5.1 Обязательства по ТЗ хакатона, которые симулятор не закрывает

Пункт ТЗ Обязанность симулятора Факт
Вход: тип съёмки (RGB, мультиспектр, ИК, LiDAR, геофизика) различать типы, для недостижимых — явная ошибка survey_type не читается нигде; ИК ловится только как несовместимость нагрузки; LiDAR/геофизика молча проходят импорт
Вход: бесполётные зоны и границы ВП геометрическая проверка нарушений константа lon > 37.63; порога 150 м (ФП-138) нет
Вход: резервные площадки посадки reserve_reachable_frac, пригодность площадок 0 вхождений в код; RESERVE_SITE_UNSUITABLE нет даже в error_codes.yaml
Вход: скорость ветра ветер влияет на время галса и допуск в прогоне ветер всегда 0; wind_max не читается
Выход планировщика KML/GeoJSON принять план без ручной правки принимается только внутренний JSON; grep kml/geojson по src/ → 0. Стыковки двух половин продукта не существует
Состав ПЗ (маршрут, точки, высоты, скорости, этапы) исполнить последовательность этапов автомата фаз нет, одна фаза survey по прямой
п. 4 Демонстрация: визуализация маршрутов 3D-пролёт, числа на экране фронтенда нет (0 файлов)
п. 5 Документация (6 артефактов) архитектура, алгоритм, запуск, API, руководство, ограничения 3 из 6; нет руководства пользователя, описания API и описания алгоритма
п. 7.2 «исполняемая версия» воспроизводимый стенд ни Dockerfile, ни compose; на чистой машине не проверялось

Приложение. Что проверено заново в этой сессии

$ .venv/bin/pytest -q                      → 50 passed in 1.12s
$ .venv/bin/sim validate --reference       → 14 строк PASS, RC=0; V-7…V-12 delta ровно +0
$ .venv/bin/sim mutate                     → 12/12 True, RC=0; detail m10 — 4 кода
$ grep -n "min(_sortie_duration" src/geoscan_sim/mission/runner.py
    54: duration_s = min(_sortie_duration(sortie), 600.0)
$ grep -n "37.63|< 100.0|>= 7.0|>= 200.0|105.0|37.6495" src/geoscan_sim/mission/preflight.py
    119, 130, 133, 163, 176, 193                       → 6 константных порогов
$ grep -rn "^from geoscan_sim" src/geoscan_sim/validator/*.py
    invariants.py:5 → engine.integrator
    mutate.py:11    → mission.preflight
    references.py:9 → uav.energy, uav.kinematics
    identities.py:5 → camera.gsd
$ sed -n '35p' tests/test_references.py
    assert "15" in v9.tolerance_note or "airspeed_max" in v9.source or True
$ find . -name '*.ts' -o -name '*.js' -o -name '*.html' -o -name '*.css' | wc -l   → 0
$ grep -oE "SIM-[A-Z]+-[0-9]+" docs/90-final/02-requirements-registry.md | sort -u | wc -l → 338
$ find src -name '*.py' | xargs wc -l | tail -1                                     → 2789

Все числа этого документа либо воспроизведены выше, либо прослеживаются до отчёта-владельца с указанием раздела. Там, где доказательства нет, стоит статус НЕ ПРОВЕРЕНО, а не «реализовано».