docs: inventory Rerun customizations and upstream dependencies

This commit is contained in:
DCCONSTRUCTIONS
2026-09-05 09:21:28 +03:00
parent b2a1b23131
commit e56eb42507
3 changed files with 279 additions and 0 deletions
@@ -3,6 +3,17 @@
Date: 2026-08-30
Status: accepted; RAVNOVES004TREE is the first migrated full-route LAB
Implementation audit, 2026-09-05: see the
[complete customization inventory](../audits/2026-09-05-rerun-customization-inventory.md)
and [upstream provenance evidence](../audits/2026-09-05-rerun-upstream-evidence.json).
The historical decision below remains recorded as written. The current code
uses private Python blueprint/reader hooks, a camera-input journal and an outer
controlled splitter; the old pointer-relay/native-divider description is no
longer its implementation. The audit also distinguishes the canonical LAB's
ready gate from Saved Sessions' progressive policy and lists unimplemented
display settings. These are upgrade dependencies and known gaps, not claims
that upstream packages have been modified.
## Context
The accepted LAB product composition was repeatedly rebuilt over independent
@@ -0,0 +1,201 @@
# Полная карта интеграции и кастомизации Rerun
Снимок кода `b2a1b23131642ac496829e467c20c8c069915be9`, 2026-09-05. Ревизия подготовлена для карточки MISSION CORE #74 «Additional Core · Переносимая кастомизация Rerun». Изменения в runtime в рамках аудита не выполнялись.
## Зафиксированное состояние · 5 сентября 2026
Репозиторий NODEDC_MISSION_CORE_m5_observatory. Принятый код: b2a1b23131642ac496829e467c20c8c069915be9. Ветка codex/m5-1-observatory перенесена в main fast-forward; прежний main 7fba39a6297e4a1792c67eccab317731abaeab72 является предком. main опубликован без переписывания истории. Остальные worktree сохранены.
Это аудит фактической реализации и карта переноса, а не обновление Rerun или новый рефакторинг. Точка отсчёта — официальный Rerun 0.36.3. Исторические формулировки ADR 0045 и карточки #66, не совпадающие с перечисленными ниже файлами, не следует считать описанием текущего кода.
Версионируемый снимок: docs/audits/2026-09-05-rerun-customization-inventory.md; машинные свидетельства происхождения: docs/audits/2026-09-05-rerun-upstream-evidence.json. Карточка #74 — полный рабочий реестр; #66 — канон интеграции.
## Официальное ядро и проверка происхождения
Активные версии строго закреплены: @rerun-io/web-viewer=0.36.3 в apps/control-station/package.json и package-lock.json; rerun-sdk==0.36.3 в pyproject.toml и uv.lock. Upstream tag 0.36.3 и npm gitHead: 6ded109d33c549e98185f7c95fa8009d44e4adef.
Заново скачан официальный npm-архив; SHA-512 совпадает с registry и lockfile. Все 12 опубликованных файлов побайтно совпадают с установленным пакетом. SHA-256 re_viewer_bg.wasm: 02d6d9c3a569d3faceb01cf89104342d970fc85e7c31a08dedd357b6c7104d2f. Тот же хеш у WASM в apps/control-station/dist/assets/re_viewer_bg-BO4B44yr.wasm. SHA-256 re_viewer.js: d2a94836dd0e6de40538c4d657cfb423b1803e354e6ee0cd550735eb5aaab09b.
Заново скачан официальный macOS ARM64 wheel Python SDK: rerun_sdk-0.36.3-cp310-abi3-macosx_11_0_arm64.whl. SHA-256 804067d6e71747f8461104988be82543b318b583a2837935558a5e79a5e9befd совпал с PyPI и uv.lock. Все 507 файлов пакетов rerun_sdk/ и rerun_bindings/ совпали с установленной .venv.
Активного postinstall-патча и импорта архивного vendor нет. vite.config.ts использует стандартный wasm plugin, target esnext, отдельный rerun-runtime.html и исключение Web Viewer из optimizeDeps ради корректного относительного URL WASM. Активный WASM и SDK не модифицированы. Это не означает отсутствия зависимостей надстроек от внутренних API: они перечислены отдельно.
## Граница и владельцы надстроек
Rerun владеет визуализацией, native store, декодированием и камерой; Mission Core владеет источниками, конфигурацией, адаптерами, внешними контролами и сохранённым display profile. Ни viewer, ни его cache не являются владельцем raw evidence, AI worker или управления оборудованием.
Основной компонент: apps/control-station/src/components/RerunViewport.tsx. Recorded-путь запускает обычный WebViewer внутри одноразового same-origin iframe; live-путь импортирует официальный WebViewer напрямую. Существует ровно один native renderer и clock на смонтированный recorded viewer, а не отдельный экземпляр на каждую половину LAB.
Действующие файлы в apps/control-station/src/components/rerun/: isolatedRerunEntry.ts, isolatedRerunHost.ts, isolatedRerunInput.ts, recordedRerunProtocol.ts, recordedRerunOwner.ts, recordedRerunFacade.ts, recordedRerunCameraJournal.ts. Прежние названия isolatedRerunOwner/rerunFacade/rerunProtocol в этой карточке были неточными.
Публичный JS-контракт: start(rrd,parent,options), stop, ready, on, open, close, open_channel, override_panel_state; get_active_recording_id/get_active_timeline/get_current_time/get_playing/get_time_range; set_active_timeline/set_current_time/set_playing. configure/get-camera-eye — методы нашей границы, не официальный API чтения native камеры.
## Изолированный runtime, протокол и освобождение ресурсов
rerun-runtime.html и isolatedRerunEntry.ts создают runtime; isolatedRerunHost.ts владеет iframe, handshake версии 2 и таймаутом 30 секунд. recordedRerunProtocol.ts задаёт команды/события; recordedRerunFacade.ts передаёт primitive JSON и синхронные Uint8Array; recordedRerunOwner.ts владеет SDK, каналами, подписками и журналом камеры внутри iframe.
SDK handles, DOM, native closures и startup promise не выдаются родителю. Dispose отклоняет родительское ожидание, закрывает каждый канал независимо от ошибок других, отписывает события и удаляет iframe. Завершившийся после dispose поздний SDK start останавливается повторно. Это прикладная изоляция жизненного цикла, не sandbox безопасности.
isolatedRerunInput.ts сейчас ретранслирует только Escape. Старое утверждение ADR о передаче pointer events родителю устарело: native gestures остаются в iframe, журнал навигации тоже находится там. Pagehide/pageshow и stale generation управляются RerunViewport и core/observation/recordedRerunLifecycle.ts.
При обновлении проверять start/stop, закрытие до загрузки iframe, закрытие во время SDK start, ошибки каналов, late callbacks, восстановление страницы. Снятие DOM само по себе не доказывает освобождение памяти: повторять последовательные open/close и измерять процесс без принудительного GC.
## Источники, admission и единые часы
Контракты: core/observation/viewerProfile.ts, recordedObservationSources.ts, recordedSessionAdmission.ts, useRecordedSessionAdmission.ts и recordedRerunLifecycle.ts; операторский playback — RerunViewport.tsx и ObservationTimeline.tsx.
Live использует stream_time и отдельную acquisition identity. Recorded использует session_time, immutable source URL/generation, согласованные application_id/recording_id, SHA-256 и byte length. Native receiver читает URL RRD; слой приложения не собирает основной архив в постоянно растущий JS Blob. Blueprint и необязательные perception/color sidecars входят в тот же store и clock.
Различать три пути: live → прямой upstream; Saved Sessions/Data → свой admission и внешняя RecordedFmp4Player.tsx для записанного видео; canonical LAB → merged RRD с native AssetVideo/VideoFrameReference внутри изолированного upstream viewer. Старый лабораторный fMP4/Three.js путь сохранён только для явно выбранного legacy comparison.
CanonicalResultRerunReplay.tsx сейчас задаёт presentationGate="ready": canonical LAB может ожидать полной native готовности. Прогрессивная политика Saved Sessions не доказывает быстрый cold open LAB. Подготовка merged RRD, загрузка/декодирование и inference модели — разные измерения. Аудит не подтверждает real-time inference.
Границы текущей реализации: blueprint transport до 1 MiB, необязательный perception payload до 512 MiB; canonical producer source/overlay/replay до 768/256/1024 MiB. Это transport/resource ограничения, не лимиты точного ввода накопления.
## Blueprint: слои, идентичность и внутренние Python API
Владелец — src/k1link/viewer/recorded.py; HTTP-контракт — src/k1link/web/session_api.py, POST /api/v1/observation-sessions/{session_id}/blueprint.rrd.
Штатные Spatial3DView(/world), Spatial2DView(/perception/camera), metrics; unified LAB использует Horizontal(camera,spatial) с column_shares. Обычные режимы spatial/perception/perception3d/metrics используют устойчивые view/container UUID; owner token входит в uuid5, reset generation 0/1 и mode-specific Tabs identity отделяют намеренный reset/смену режима от обновления слоёв. auto_layout и auto_views выключены, native TimePanel скрыт, общий timeline session_time.
EntityBehavior меняет видимость /world/points, /world/trajectory, /world/costmap, perception-слоёв и /perception/camera/{image,detections,segmentation/city,segmentation/vegetation}. VisibleTimeRanges применяет накопление к точкам/траектории; динамическая perception остаётся latest-at без искусственных шлейфов. Размер точек — штатный Points3D visualizer override. План меняет eye, не геометрию данных.
Версионно чувствительная часть: bindings.new_blueprint, RecordingStream._from_native, Blueprint._log_to_stream, bindings.send_blueprint, memory_recording().storage, binary_stream/to_native. Это прямое использование внутренних/низкоуровневых Python hooks, несмотря на неизменённый SDK. Один source blueprint stream живёт на владельца; обновления добавляются последовательно, активная копия повторно активируется.
Обычные переключения слоёв не записывают eye. 3D/план/reset применяют явные пресеты; FOLLOW имеет отдельный протокол восстановления. При обновлении надо проверять семантику active blueprint clone и сохранение runtime eye, а не только то, что Python-функции существуют.
## Blueprint lease, bounds и цветовые cache
src/k1link/viewer/recorded_blueprint_lifecycle.py: ключ (application_id, recording_id, blueprint_session_id), idle TTL 300 секунд, reaper 30 секунд, максимум 32 entries, release tombstones до 4096. Renew открытого владельца каждые 30 секунд; render/release сериализованы; активный render не обрывается по TTL. Есть shutdown cleanup. Durable записи при release не удаляются.
Frontend core/observation/recordedBlueprintLifecycle.ts отправляет renew/release в /blueprint-lifecycle; при закрытии bounded keepalive с таймаутом 5 секунд. Эта граница относится к ephemeral viewer resources, не к остановке вычислений.
recorded_camera_bounds.py использует bindings.RrdReaderInternal и названия Arrow-компонентов. LRU на 8 поколений keyed by path/size/mtime хранит scene bounds и индекс translation /world/sensor_pose на session_time. RRD не перечитывается при каждом переключении. Максимальный zoom-out выводится из диагонали сцены и upstream factor 5.
device_plugins/xgrids_k1/recorded_point_colors.py пишет цветовой RRD override в тот же recording, без дублирования геометрии/траектории/видео/AI. Режимы intensity/height/distance/rgb/class; палитры turbo/viridis/plasma/grayscale/custom. Cache индекса по умолчанию 384 MiB, payload 192 MiB; отдельный payload ограничен 256 MiB. Правила fallback/метаданных принадлежат этому адаптеру.
RrdReaderInternal, Arrow component schema, правила слияния override и memory ownership — обязательные точки проверки при смене SDK.
## Навигация и FOLLOW: фактический механизм
recordedRerunCameraJournal.ts реконструирует position/lookTarget/eyeUp по pointer orbit/pan/roll и wheel. Публичного WebViewer API для чтения текущего native eye в 0.36.3 нет: журнал не является снимком из ядра.
Скопирована модель поведения из upstream eye.rs: rotation 0.004, pan 0.001 × radius, wheel exp(delta/200), отдельный pinch/ctrl divisor 100, line scroll factor 8, near radius 0.02, ограничение pitch 0.99 × π/2, scene-derived max radius. Эти численные и событийные правила — контракт переноса даже без vendor patch.
Коммит b2a1b23: при FOLLOW off session_api.py добавляет к journal offset текущий /world/sensor_pose и записывает мировую eye-позу; камера остаётся на месте, сканер продолжает движение. При FOLLOW on сначала устанавливается tracking, затем после двух animation frames восстанавливаются направление/up/радиус относительно текущего пивота. Это компенсирует upstream auto-fit нового tracking entity. Обычные TGS/DDRNet/рамки не должны писать eye или пересоздавать viewer.
Проверенный сценарий и результаты предыдущей browser acceptance сохранены отдельным историческим блоком. Не распространять это доказательство на все native gestures: WASD, double-click/picking fit, inertia и другие неотражённые журналом действия могут расходиться с восстановленной позой. Полная замена журнала официальным pose API — возможное последующее улучшение, если такой API появится; в этой ревизии не выполнялась.
Точная исходная опора: https://github.com/rerun-io/rerun/blob/0.36.3/crates/viewer/re_view_spatial/src/eye.rs .
## Viewport UI, разделитель и native chrome
apps/control-station/src/components/laboratory/CanonicalRecordedLabReplay.tsx размещает внешний @nodedc/ui-react SplitPane над одним native viewer. Контролы принадлежат секциям overlay; separator меняет controlled primarySize. CanonicalResultRerunReplay.tsx передаёт размер в native Horizontal column_shares с debounce 75 ms. Это управляемая внешняя компоновка плюс синхронизация blueprint, а не отслеживание перетаскивания native Rerun divider.
У canonical result начальное соотношение 46/54. Внешний SplitPane ограничивает обе стороны минимумом 24%, backend share принимает 10–90%. Если источники дают только camera или spatial, выбирается одно окно. Панель каждого окна находится сверху слева в его границах; pointer-events разрешены для контролов/разделителя, прозрачная остальная область не должна блокировать native input.
styles/m4-replay-threat.css: flex-wrap и display:contents обеспечивают перенос отдельных групп/контролов по доступной ширине; под глобальные refresh/fullscreen резервируется 7rem справа. 3D/план и FOLLOW остаются в общей адаптивной строке spatial-панели. Общие действия принадлежат LaboratoryEvidenceViewer.tsx. Refresh здесь — явный сброс положения видов через reset generation; не произвольная перезагрузка данных.
styles/spatial.css обрезает native chrome сверху на 72px (три ряда по 24px). Это чувствительно к версии native UI и масштабу, хоть WASM не патчится. Старый фиксированный camera interaction lock не включён в canonical profile.
Сегодня это реализация camera + spatial/single pane с фиксированными видами, а не готовый универсальный редактор дерева из 50 viewport. Расширение дерева компоновки и проверка resource budget для десятков окон остаются отдельной задачей.
## Конфигурация, онтология и точный смысл кнопок
Проекция модулей и viewer layers: src/k1link/observatory/domain_ontology.py, portable_setup_projection.py, frontend core/observatory и CanonicalResultRerunReplay.tsx. Сохранённые moduleIds/viewerLayers определяют доступные панели и кнопки; отсутствующие возможности не должны появляться из текста заголовка. Точные конфигурационные значения и display profile отделены от immutable результатов расчёта.
КАМЕРА управляет только /perception/camera/image; рамки и segmentation независимы от фона камеры. РАМКИ доступны по наличию detections. EOMT → segmentation/city, DDRNET → segmentation/vegetation. Если оба semantic toggles включены, текущий selector отдаёт приоритет EoMT; это не одновременная визуализация двух масок.
TGS → /world/costmap. ИСХ. ТОЧКИ и ЛОК. SLAM используют одно sealed /world/points: showPoints = source || localSLAM; SLAM дополнительно включает trajectory и выбранное накопление, source-only использует 0. Это не два разных набора математических/декоративных точек. Настройки не меняют расчётные raw данные.
3D/ПЛАН — явные camera presets; СЛЕДОВАТЬ — tracking текущего sensor_pose с восстановлением eye. Профиль отсутствующего слоя не должен запускать inference или создавать имитацию evidence.
## Display profile LAB: хранение и применяемые поля
Frontend: CanonicalResultRerunReplay.tsx, core/observatory/labViewProfile.ts. Backend: src/k1link/observatory/lab_view_profiles.py, web/modular_observatory_api.py. Профиль привязан к result_id, хранится отдельно от immutable calculation config; запись файла через temp/fsync/atomic replace.
Изменения отображаются сразу; localStorage хранит локальный draft, при открытии читается серверный профиль. Закрытие окна настроек отправляет PUT. Окно закрывается и при ошибке; compact error toast сообщает, что серверная запись не подтверждена. Успех в памяти или localStorage не равен подтверждённому сохранению на сервере.
Поля: point_size, accumulation_seconds, color_mode, palette, show_grid, show_labels, show_camera_frustums. Накопление: slider 0–500 s, точный ввод конечного значения ≥0 без верхнего product cap. Point size: slider 0.110 px, точный ввод ≥0.1 без верхнего cap. Нормализация: накопление до целой секунды, размер до одного десятичного знака; отрицательные/NaN/Infinity недопустимы.
Размер, диапазон накопления, цвет/палитра и grid подключены к viewer. show_labels и show_camera_frustums сохраняются и доступны в UI, но не входят в blueprint request/recorded.py текущего canonical LAB: визуальное применение этих двух настроек НЕ подтверждено и не реализовано в этом пути.
Layer toggles, FOLLOW, camera eye и split ratio не записываются в этот durable display profile; это состояние текущего просмотра. Проверка cache-clear должна касаться серверно сохранённых полей, а не обещать сохранение всего состояния viewport.
## RRD producers и данные для официального viewer
Данные — отдельная часть карты совместимости, не патч ядра. src/k1link/device_plugins/xgrids_k1/rrd_export.py экспортирует базовые points/pose/trajectory; viewer/rerun_bridge.py обслуживает live SDK/GRPC, RH_Z_UP и stream_time. calibrated_overlay.py добавляет калиброванную evidence projection.
src/k1link/laboratory/canonical_rerun_overlay.py формирует совместимые AssetVideo, VideoFrameReference, EncodedImage masks, Boxes2D и Clear. Renderer identity: upstream-rerun-0.36.3-encoded-optimized-v6, replay identity: upstream-rerun-0.36.3-canonical-replay-v1. Источник store identity читается через RrdReaderInternal. Видео приводится ffmpeg к native-compatible H.264; immutable lineage/digest связывают cache с исходной записью и renderer.
CLI Rerun применяется для merge/optimize. Профиль оптимизации overlay: object-store, max-size 4MiB, max-rows 512, num-pass 20. Поведение CLI, поддержка codecs/components, store identity и порядок latest-at/Clear должны повторно проверяться при обновлении; менять имя renderer без повторной materialization недостаточно.
Другие владельцы Rerun evidence: observatory/portable_replay.py, portable_semantic_replay.py, portable_object_replay.py, portable_tgs_replay.py; sessions/lab_cache.py и canonical_lab_spatial.py; compute/results.py, integrated_perception.py, fusion_epoch.py. Их логирование надо сверять с SDK при обновлении даже если viewport UI не менялся.
application_id, recording_id, временная шкала и entity paths обязаны совпадать у base/sidecar. Старые sealed results нельзя переписывать ради смены viewer: производные cache перестраиваются с новой renderer identity и проверкой lineage.
## Архивный форк 0.34.1 · сохранён, не активен
Полный старый набор находится в apps/control-station/vendor/rerun-web-viewer-0.34.1/: BUILD_INFO.md, NODEDC_ZOOM_TO_CURSOR.patch, re_viewer.nodedc.js, re_viewer_bg.nodedc.wasm. Upstream commit 4efb18f17f6f0e41985cda99a2bdcd012febc8d5; история до миграции помечена baseline/custom-legacy-before-canonical-rerun-2026-08-30.
Rust patch менял eye.rs и ui_3d.rs: zoom вокруг точки под курсором/focus plane, orbit вокруг picked point, dolly после near radius 0.02, scene-scale floor скорости, persistent follow при orbit/zoom, восстановление последнего rendered eye после blueprint activation. Эти возможности не следует автоматически приписывать текущему upstream 0.36.3.
scripts/patch-rerun-web-viewer.mjs также содержал ready/handle guard watchdog и общий keyup listener; scripts/transform-rerun-web-viewer-glue.mjs — per-instance WASM glue, teardown/finalization/destructor guards. Installer проверяет версию строго 0.34.1 и известные хеши. Он больше не вызывается postinstall; импортов архивной пары в активной сборке нет. Не запускать его для 0.36.3.
Воспроизводимость старой сборки описана BUILD_INFO.md: Rust 1.92.0, Binaryen 117, rust:1.92-bookworm с digest e90e846de4124376164ddfbaab4b0774c7bdeef5e738866295e5a90a34a307a2, upstream builder и transform script. Исторические Rust tests: 10 passed, не повторялись в этом аудите.
Архивный WASM SHA-256 ffe7543d28bb3394f289f6299de43d038767eef83d781c2b7f8f5683308a0469; glue SHA-256 0f7b76c9f24cbd8437021b5d37499894aeadc586183e422ebc82ef556d7b8339. Этот архив — свидетельство прежних изменений, не инструкция автоматически возвращать их при следующем обновлении.
## Что остаётся чувствительным и что не подтверждено
1. SDK не изменён, но blueprint transport и чтение RRD зависят от private bindings. Универсальная переносимость без адаптации не доказана.
2. Журнал камеры повторяет часть native navigation. Полная идентичность для всех способов навигации не доказана; текущая FOLLOW-компенсация зависит от auto-fit и порядка кадров.
3. Native chrome crop 72px и синхронизация external/native layout зависят от UI и blueprint поведения Rerun.
4. show_labels/show_camera_frustums сохраняются без применения в canonical LAB; два semantic toggles не дают две одновременно показанные маски.
5. Source/SLAM — два способа представления одной геометрии. Раздельные raw/math и decorative geometry здесь не реализованы.
6. Конструктор произвольного числа viewport и работа 50 окон не реализованы/не квалифицированы. Лимит blueprint owners 32 нельзя трактовать как поддержку 50 viewers.
7. Cold materialization, полная готовность LAB и освобождение memory требуют самостоятельных измерений. Быстрое переключение слоёв не доказывает real-time inference.
Эта ревизия фиксирует ограничения, не устраняет их рискованным изменением принятого viewer. При следующем обновлении сначала квалифицировать новые публичные API и затем отдельно решать, какие private adapters можно упростить.
## Свидетельства этой ревизии и воспроизведение
5 сентября 2026 повторно сверены upstream npm/PyPI archive hashes, installed files и built WASM. Матрица файлов/методов составлена по коду b2a1b23, а camera/blueprint зависимости — по исходникам официального тега 0.36.3. Исходные хеши и archive URLs записаны в JSON-свидетельстве.
Повторно запущено: node --test test/rerunWebViewerVendor.test.mjs test/recordedRerunCameraJournal.test.mjs test/recordedViewerResourceLifecycle.test.mjs из apps/control-station — 16 passed. Из корня: .venv/bin/python -m pytest -q tests/test_recorded_blueprint_lifecycle.py tests/test_recorded_camera_bounds.py tests/test_observatory_lab_view_profiles.py — 12 passed.
Полная предыдущая проверка принятого FOLLOW-кода: 759 frontend tests, 65 backend tests, typecheck/build/Ruff и ручной browser-сценарий указаны в историческом блоке; в этом документальном аудите полные suites и browser-сценарий заново не выполнялись. Runtime-код не изменён.
Для независимого повторения происхождения: получить архив точной версии из npm registry/PyPI; сверить digest с lockfile и registry; сравнить каждый файл npm package с node_modules, файлы rerun_sdk/rerun_bindings из wheel с .venv; отдельно SHA-256 установленного и dist WASM. Не считать один version string доказательством неизменённого пакета.
Официальные исходники: https://github.com/rerun-io/rerun/blob/0.36.3/rerun_js/web-viewer/index.ts ; https://github.com/rerun-io/rerun/blob/0.36.3/crates/viewer/re_view_spatial/src/eye.rs ; https://github.com/rerun-io/rerun/blob/0.36.3/rerun_py/rerun_sdk/rerun/blueprint/api.py .
## Обязательная проверка при следующем обновлении
- [ ] Создать отдельную ветку от зафиксированного main; записать старую/новую пару SDK+Web Viewer, upstream commit, lockfile и archive hashes. Не запускать installer архивного форка.
- [ ] Сверить публичный WebViewer API, загрузку Vite/WASM, iframe handshake/facade и события; проверить stop, late start и закрытие всех каналов.
- [ ] Сверить private blueprint hooks, RrdReaderInternal/Arrow schema, active clone semantics, UUID/reset identity; отдельно подтвердить lifecycle renew/release/TTL.
- [ ] Сопоставить eye.rs/ui_3d.rs: orbit/pan/roll/wheel/pinch, min/max radius, tracking auto-fit; повторить FOLLOW off/static/on при текущем pivot с тем же масштабом.
- [ ] Проверить native chrome crop и layout на обычном/полном экране; подвигать разделитель в обе стороны, проверить локальные панели и перенос без перекрытия refresh/fullscreen.
- [ ] Открыть полную LAB, DDRNet и TRAVEL TGS; отдельно camera-only/spatial-only. Проверить каждую доступную кнопку, raw camera off при работающих masks/boxes и все слои off.
- [ ] При play и pause переключить TGS/DDRNet/boxes/source/SLAM: eye и zoom сохраняются, нет прежней двухсекундной задержки. Записать измерения, не ограничиваться видом активной кнопки.
- [ ] Приблизиться, отдалиться, pan/orbit/roll, использовать native keyboard/double-click и повторить follow. Несовпадения журнала отмечать отдельно, не скрывать.
- [ ] Сохранить cloud profile через закрытие, проверить server readback, открыть после очистки browser storage. Проверить 300/500 секунд и точный ввод выше slider; ошибка PUT не запирает окно.
- [ ] Квалифицировать show_labels/show_camera_frustums и двойной semantic selection; известный пробел не отмечать выполненным без подключения и UI-проверки.
- [ ] Проверить export/merge/optimize, codecs, masks/boxes/Clear, color override и lineage на новых SDK. Новый renderer digest и cache строить без изменения sealed source/results.
- [ ] Проверить Saved Sessions и live отдельно от canonical LAB: admission, пять seek на pause, play/resume, clocks, decoder recovery, отсутствие зависимости replay от worker.
- [ ] Измерить cold/warm open и последовательные open/close memory без forced GC; RRD/receiver/canvas identity стабильна при playback/layer changes.
- [ ] Запустить профильные tests, typecheck/build и ручную UI acceptance. Зафиксировать версии, diff адаптеров, результаты, отклонения и пригодный scoped rollback до main.
- [ ] Rollback делать откатом коммита обновления/lockfiles и пересборкой его dist/cache; не применять старый vendor patch или глобальный reset параллельной работы. Канонический сервис оставить на 8000.
## Исправление FOLLOW · 5 сентября 2026
Коммит b2a1b23, ветка codex/m5-1-observatory. При FOLLOW off журнал камеры раньше передавал координаты без смещения текущего /world/sensor_pose: камера возвращалась к началу маршрута. При FOLLOW on upstream Rerun 0.36.3 выполняет автоматическое кадрирование нового tracking entity и меняет дистанцию.
Исправление в надстройке: recorded_camera_bounds.py индексирует translation /world/sensor_pose в том же generation-keyed LRU; session_api.py переводит eye offset относительно пивота в мировые координаты на текущем cursor. При отключении FOLLOW записывается текущая мировая поза. При включении сначала устанавливается native tracking, затем после двух animation frames восстанавливаются направление, up и радиус оператора относительно текущего пивота. Обычные переключения слоёв не записывают eye. recorded.py больше не применяет стартовый пресет при смене FOLLOW; пресеты остаются для явных 3D/план/reset.
Файлы: apps/control-station/src/components/RerunViewport.tsx; src/k1link/viewer/{recorded.py,recorded_camera_bounds.py}; src/k1link/web/session_api.py. Ядро и vendor-сборка Rerun не изменены.
Проверено: 65 backend-тестов по camera bounds, RRD export и session API; 759 frontend unit-тестов; typecheck; production build; Ruff; git diff --check. Browser acceptance на RAVNOVES004TREE с DDRNet-39, RF-DETR, TRAVEL TGS и LiDAR: приближение при FOLLOW on, off без изменения кадра, воспроизведение с неподвижной мировой камерой от 00:39.215 до 01:26.491, on с переносом к текущему пивоту при сохранении масштаба, повторный off без прыжка к старту. Ошибок уровня error в браузере не зарегистрировано.
При обновлении Rerun повторно проверить правило auto-fit нового tracking entity, порядок активации blueprint и математику журнала навигации. Основание upstream: https://github.com/rerun-io/rerun/blob/0.36.3/crates/viewer/re_view_spatial/src/eye.rs#L893-L991 .
@@ -0,0 +1,67 @@
{
"npm": {
"version": "0.36.3",
"tarball": "https://registry.npmjs.org/@rerun-io/web-viewer/-/web-viewer-0.36.3.tgz",
"integrity": "sha512-LMGnsxRmY5UwiGras2dZrMnEYkow5Xr4v+1hAUSspXWPPiilMqoz9G77jo8Ps/deAaX81TnOq123DFO8iX/Ulw==",
"git_head": "6ded109d33c549e98185f7c95fa8009d44e4adef",
"compared_file_count": 12,
"mismatches": [],
"hashes": {
"index.js": "009aa5f66c8674ea268a91926c00e2f82cc7a7b7e5535056d93bd4656d6f6812",
"re_viewer.js": "d2a94836dd0e6de40538c4d657cfb423b1803e354e6ee0cd550735eb5aaab09b",
"index.d.ts": "649637dad4e50ef4f2310fc1920b580d16832226a0dda5238355059bf167efba",
"index.ts": "087b25170f720a28aa69c411903133286238900050ac775d2cc511b919846696",
"re_viewer_bg.wasm": "02d6d9c3a569d3faceb01cf89104342d970fc85e7c31a08dedd357b6c7104d2f"
}
},
"upstream_tag_commit": "6ded109d33c549e98185f7c95fa8009d44e4adef",
"sources": [
{
"path": "rerun_js/web-viewer/index.ts",
"sha256": "087b25170f720a28aa69c411903133286238900050ac775d2cc511b919846696"
},
{
"path": "crates/viewer/re_view_spatial/src/eye.rs",
"sha256": "491cf8143630ce7d955689d39bfe02b306172a30005135a1f86cdf348424fe68"
},
{
"path": "crates/viewer/re_view_spatial/src/ui_3d.rs",
"sha256": "b552f343dd5eb2970827d0b55d3f2febd2d9cfc663d1d5fcc44b5477b33a8ed8"
},
{
"path": "rerun_py/rerun_sdk/rerun/blueprint/api.py",
"sha256": "00db63587a2daca04d50a38eadef4852b2aaba70e45aa044597189a3f3ea5c1f"
}
],
"python": {
"version": "0.36.3",
"official_wheel": "https://files.pythonhosted.org/packages/43/ff/e8ce81a4fa451f232abb10f0737c5fa8c812a4b2979bda2f655c58c478eb/rerun_sdk-0.36.3-cp310-abi3-macosx_11_0_arm64.whl",
"wheel_sha256": "804067d6e71747f8461104988be82543b318b583a2837935558a5e79a5e9befd",
"compared_package_files": 507,
"mismatches": []
},
"built_wasm": [
{
"path": "apps/control-station/dist/assets/re_viewer_bg-BO4B44yr.wasm",
"sha256": "02d6d9c3a569d3faceb01cf89104342d970fc85e7c31a08dedd357b6c7104d2f"
}
],
"audit_date": "2026-09-05",
"application_code_commit": "b2a1b23131642ac496829e467c20c8c069915be9",
"methodology": {
"npm": "Official registry tarball integrity matched registry and lockfile; all published package files byte-compared with installed node_modules package.",
"python": "Official PyPI macOS ARM64 wheel SHA-256 matched PyPI and uv.lock; rerun_sdk and rerun_bindings package files byte-compared with installed .venv.",
"built_wasm": "SHA-256 of production dist WASM compared with the verified npm WASM.",
"upstream_sources": "Pinned tag source files downloaded from the official rerun-io/rerun repository; tag commit compared with npm gitHead.",
"scope": "Documentation-only audit; no SDK, viewer or runtime source changes."
},
"legacy": {
"version": "0.34.1",
"active": false,
"upstream_commit": "4efb18f17f6f0e41985cda99a2bdcd012febc8d5",
"hashes_verified": {
"re_viewer_bg.nodedc.wasm": "ffe7543d28bb3394f289f6299de43d038767eef83d781c2b7f8f5683308a0469",
"re_viewer.nodedc.js": "0f7b76c9f24cbd8437021b5d37499894aeadc586183e422ebc82ef556d7b8339"
}
}
}