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.py — 0 % (CLI и есть предмет сдачи), contracts/loader.py — 0 % (весь слой контрактов мёртв) |
| Детерминизм 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:35 — or 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-126 — if 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_id → RUN_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 (actual ← metrics.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.json → status: 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
Все числа этого документа либо воспроизведены выше, либо прослеживаются до отчёта-владельца с указанием раздела. Там, где доказательства нет, стоит статус НЕ ПРОВЕРЕНО, а не «реализовано».