feat(fleet): add board observation center with live sources and maps

Add adaptive per-vehicle layouts, full-panel dragging, source controls and automatic preview recovery for RealSense, Insta360 X4 and XGRIDS K1 observation views. Integrate cached Cesium map layers through the private NAS gateway link, retain bounded sensor command receipts, and document validation and operational handoff.
This commit is contained in:
DCCONSTRUCTIONS
2026-09-10 22:12:05 +03:00
parent 5f75afb720
commit be58d589e2
48 changed files with 1575 additions and 83 deletions
@@ -1792,3 +1792,133 @@ Fresh Core readback: same vehicle/node/device IDs, both cameras online;
D455 streaming; X4 idle/preview0/recording0/recoveryfalse/preview_wantedfalse.
Owner informed installation completed and no further password needed; only
Power-off with USB retained is awaited for MANUAL02. No new wake issued yet.
## 2026-09-10 — OBS01: board observation UI qualification
Owner requested a board-scoped multi-panel observation center. Runtime baseline:
D455 capture streaming, X4 preview0/recording0/recovery disabled. The product UI
issued bounded X4 preview.start/preview.stop operations only; no SD recording,
photo, preparation, SDK installation or Ubuntu runtime edits. Existing Node
0.8.21-3/X4 0.1.3-9 remains the installer-owned baseline.
Qualified the published X4 frame as a 1280×640 pair of fisheye views. The new
observer uses one WebRTC peer/decoder and two canvas crops, without stitching.
A WebKit hidden-video pause was caught during QA and fixed with explicit muted
playback; both lens views then showed live images alongside D455. Crops are
frame halves, not a proved chassis-relative left/right camera mounting.
Repeated source changes exposed Core's 32-command limit counting completed
receipts for ten minutes. Local Core correction retains 32 active slots and
bounds receipt history at 128; only expired terminal receipts can be reclaimed.
34 fleet tests cover completion, saturation and replay rejection. No Node patch
was required. Canonical LaunchAgent apply used identical predecessor/desired
plist SHA 6b651aedb54236f76bf062a2319d9223f0b00f7d264451b3bbaccbee0896e065;
Core PID74340→85056, health accepted. Apply report SHA256
78280b731a41e4f78df1174b3363920118f7dd9e4b178e33dbebe69be0deb590.
Final API readback: board online, D455 streaming, X4 idle/preview0/recording0.
No temporary capture or Ubuntu job remains. User-facing observer retains the
original D455 live source. Private timestamped/monotonic acceptance report SHA256
6d51159c3eff97e19297c71cef40a57e391e2e7aacbac1ff0909cfdcfcea6922.
Validation: 826 Control Station tests, 8 focused architecture/observer tests,
Control Station and Node UI types, production build; browser normal/expanded,
Escape priority, layer selection, hide/restore, split and ordering persistence.
Real K1 dual-view and server map cache acceptance are not claimed: K1 absent,
configured local Map Gateway18103 unavailable. See 08_BOARD_OBSERVATION_CENTER.md.
Rollback: restore predecessor source/build and reload the same canonical Core
through the LaunchAgent lifecycle; do not edit the board or SDK. Layout v1 is
browser-local and independent for each vehicle; reset uses the product control.
### OBS02 — direct observer preview start, 2026-09-10
User reported blank X4 panels after OBS01 left preview stopped. Added one shared
preview.start action to X4Observation, exposed in both lens panels with common
pending/error state and an in-flight guard. Uses the existing versioned operation
transport and exact device/session identity. No installer, Node service, SDK,
recording or Ubuntu changes. Closing observer panels still releases viewer peers
only and does not stop camera capture.
Actual GUI start accepted: one 1280×640 decoder, two live lens canvases, D455 live.
Current final readback supersedes OBS01 cleanup state: X4 online/streaming,
preview=1, recording=0. Preview is durable operator state for this request and
is intentionally left on. Frontend build/typecheck passed. Private evidence
SHA256 9fef991a516ab516e7530c7c1b3cfb80056a619216d7d899ee67ea81ba44022b.
Rollback is frontend-only: remove the action and rebuild; it does not mutate
the prepared board or stop an ongoing preview.
### OBS03 — automatic opening and stalled-preview recovery, 2026-09-10
Owner explicitly requires camera initialization on opening Board Observation.
X4 and D455 now activate preview automatically from fresh exact-session inventory.
Two X4 lens windows share one start and one peer. Already streaming capture is
preserved. RealSense start uses record=false; X4 uses preview.start only.
Viewer retries are bounded separately from camera-source recovery. Confirmed X4
source staleness triggers preview stop/start only with recording=0, with session
revalidation, stop-failure short circuit and two-attempt budget until stable live.
These are existing installer-owned API operations; no SDK, service, library,
configuration, package or Ubuntu mutation was needed.
Live acceptance: original X4 stale source recovered without a manual start;
then GUI stopped both cameras, API confirmed both idle and X4 preview0/recording0,
and one Center opening started D455 RGB640×480 plus both X4 lenses1280×640.
No manual preview-start click was used. Final both online/streaming, X4 preview1,
recording0, no D455 recording. Previews remain on for the operator.
11 focused tests, Control Station build/types and Node UI types passed. Evidence
SHA256 c99c2e929618df21725ea1b8dcce08b242b6ab49f1b4b3b9cb5a125b1bad7124.
Rollback: restore prior frontend and rebuild; no board reinstall or cache reset.
### OBS04 — viewer stability and presentation, 2026-09-10
Fixed false peer/source recovery when a hidden or clipped X4 decoder stopped
requestVideoFrameCallback while RTP decoding continued. A two-second decoded-frame
check now runs independently of DOM painting. A stale source sample retains the
last image with a delay status; source restart requires twelve continuous seconds
of stale fresh telemetry. Missing telemetry and peer failure do not authorize
capture restart. Peer failure closes the previous peer before bounded backoff.
Inventory SSE loss gets a bounded fifteen-second grace and HTTP verification.
Both old and new frontend instances were inspected; the stale Chrome build was
reloaded so it could no longer independently restart shared capture. From
17:27:49.636Z through 17:52:39.435Z, D455 media time advanced 154.753→1644.621 s
and X4 123.635→1613.433 s, without reset in the observed samples. Both final
videos were unpaused, readyState=4, D455640×480 / X41280×640. This demonstrates
sustained decoding across the interval, not zero dropped frames. No Ubuntu, SDK,
service or recording mutation. Prepared Node0.8.21-3/X4plugin0.1.3-9 preserved.
Service notices reduced 30% to 11.2px, first-person UI text removed, and failed
Cesium canvas hidden while its panel retains the same complete rounded black
surface. Control Station 838 tests, focused20, both frontend typechecks and
production build passed. Canonical Core8000 health remained ok. Private acceptance
SHA256 d885939be21b398970c41e5471d2580c0d10493f4dbff807bbdbe94790f64739.
NAS map access is explicitly owner-approved and separately staged through Platform
runner; it has not yet been applied. Camera acceptance does not claim map success.
Rollback is restoration of prior frontend source/build using canonical lifecycle;
no board reinstall or automatic capture stop is required.
### OBS04B — resume browser-paused RealSense after map expansion
Final visual QA reproduced a distinct presentation failure: at18:10:12Z the
RealSense element was paused at media1996.686s while RTP was still decoding
and the status said live. Map expansion temporarily detaches the panel portal;
WebKit can pause its video. Added previewPlayback to resume the same muted
stream on a two-second presentation check/visibilitychange. Pending play calls
are coalesced, rejected hidden playback retries later, disposed views do not
resume. A paused visible video no longer receives a live badge. This action
never replaces a peer or issues camera capture/recording commands.
Focused18 tests, full840, both frontend typechecks and production build passed.
New asset app-DGION5Hm.js loaded on canonical Core8000. Before map expansion
18:14:26.463Z media timesD45536.228/X436.262. Map held expanded until
18:14:51.338Z, then restored. At18:15:52.519Z both were ready4/unpaused,
mediaD455122.339/X4122.355 with no timeline reset. Fresh fleet readback: both
online/streaming, X4preview1/recording0, no D455 recording. Node/SDK unchanged.
Private evidenceSHA b1d3c3c382866304ccac80e8cab9b49ca1a0ea5836af715baf96b9f3b4923ef9.
Map network acceptance also completed: after Windows connector became healthy,
24 new buildings objects (15161307bytes) were appended to NAS cache, entries
71774→71798/bytes1519820206→1534981513, while failure count remained5. Previous
AMD connection refusal is resolved; cold data still requires its documented
Windows Docker/VPN path. Cached map and all camera views left open.
+311
View File
@@ -0,0 +1,311 @@
# Бортовой центр наблюдения
Product-surface brief, 10.09.2026. Владелец прямо запросил эту композицию и оба
входа: в строке аппарата и в карточке БК. Новая верхняя навигация не требуется.
- Задача оператора: одновременно видеть визуальные источники выбранного борта.
Entity — борт; источники принадлежат конкретным device/session identities.
- Выбран отдельный режим внутри «Парк → Аппараты», с возвратом к конфигуратору.
Альтернатива — расширить конфигуратор — отклонена: формы мешают наблюдению и
отнимают место у видео. Новый product root не нужен.
- Источники приходят из inventory и model contributions. RealSense — одно окно
с выбором реально объявленного слоя; X4 — две половины парного кадра; K1 —
Rerun Point Cloud 3D, отдельный ракурс сверху и опубликованная Cam Right.
- Карта — общий @nodedc/map-cesium-react; presentation mapper переиспользуется
с WorldMapWorkspace. Все provider-запросы идут через /api/v1/map/gateway,
cacheIntent enabled/no_overwrite=true. OSM buildings asset 96188, imagery 2,
terrain 1. Координаты борта не выдумываются: без GNSS маркера аппарата нет.
- Одна preview-сессия на пару X4/K1. Перекомпоновка меняет только размещение
существующих DOM mounts, не захват или identity. Видео использует существующий
WebRTC transport, K1 — существующий Rerun host/stream. Это единая рабочая область
разных renderer-ов, не конвертация видео в RRD и не новый recorder.
- Контролы: Button/IconButton (eye, sliders, activity, settings, expand/minimize,
close), Select, Switch, GlassSurface, ApplicationPanel, SplitPane,
DragDropRoot/DraggableItem/DropZone из NODE.DC Design Guideline. Новых shared
visual entities нет. Drag меняет порядок панелей, SplitPane — размеры.
- Состояния: loading, нет визуальных устройств, все окна скрыты, источник offline,
preview idle, connecting, live, stale, error/retry. Скрытие не останавливает
запись. По уточнённому требованию владельца открытие центра автоматически
запускает предпросмотр подготовленных RealSense/X4; запись не запускается.
- Layout принадлежит борту и локальному браузеру: порядок, скрытые источники,
выбранные слои, проценты split и режим компоновки; fullscreen — временный.
- Приёмка: оба входа, три горизонтальные кнопки, адаптивный состав панелей по inventory,
разные экземпляры, split/drag/hide/restore, слои, fullscreen/Escape, persistence,
свежий RealSense/X4 поток, автоматическая активация preview и отсутствие record effects.
Референс поведения: https://docs.foxglove.dev/docs/visualization/panels и
https://docs.foxglove.dev/docs/visualization/layouts. Все три присланных примера просмотрены в авторизованном Chrome: UGV, Argo
и quadruped. Проверены многопанельная композиция, отдельные камеры, карта,
вид сверху и свободный 3D. Временная вкладка закрыта. Зависимость Foxglove от Rerun
не установлена и не является основанием реализации.
Read-only baseline: Core 8000 alive, Rover online, D455 streaming, X4 idle.
Проверка через штатный UI: X4 preview.start → живое видео 1280×640 с двумя
fisheye-изображениями → preview.stop подтверждён доступной кнопкой START.
SD recording не запускалась; SDK/runtime/Ubuntu не менялись. Left/Right относятся
к половинам опубликованного кадра, не к доказанному положению камеры на шасси.
## Реализация и проверка 10.09.2026
- Два входа в центр и три горизонтальные кнопки в карточке БК.
- Стабильные portal mounts сохраняют video/canvas/native viewer при смене
split, порядка и fullscreen. Скрытие всей группы отключает viewing peer,
но не захват и не запись. Выход закрывает peer штатной close-peer.
- Layout v1 привязан к vehicle ID: order, hidden, selected layer, arrangement,
bounded split proportions. Неизвестные/повреждённые browser values проверяются.
- Для K1 один RRD peer раздаёт байты двум изолированным Rerun realms. Собственные
RBL assets содержат только конфигурацию; generator использует закреплённый
Rerun 0.36.3 и application ID существующего bridge. Реальный K1 отсутствует
в текущем inventory: аппаратная приёмка двух ракурсов остаётся открытой.
- Реальный D455: RGB 640×480, глубина, оба ИК-канала, облако точек и IMU показаны
в центре. X4: один WebRTC decoder 1280×640 и два живых crop canvas. WebKit
требовал явного play() для decoder video; исправлено и подтверждено кадрами.
- Fullscreen вынесен в стабильный body portal: родительская transform больше
не ограничивает viewport; использован canonical overlay layer. Escape сначала
принадлежит открытым диалогам/спискам, затем восстанавливает центр/панель.
- Frontend: 826 tests passed; дополнительный architecture/observation pass 8/8;
типы Control Station и Node UI проходят. Production build проходит; остался
прежний bundler advisory по размеру основных чанков.
- Общий UI package пересобран из уже существующих source, потому что его dist
types отставали от LoadingRegion/loading controls. Source DG не менялся.
## Существующая очередь операций Core
Во время проверки много переключений слоёв заполнили 32 receipt slots на десять
минут. Это блокировало даже preview.stop, хотя операции уже завершились.
Исправлен учёт: максимум 32 одновременно ожидающие/исполняемые команды сохранён;
receipt storage отдельно ограничен 128. При заполнении удаляются только terminal
receipts с истёкшим deadline. Их повторная отправка не может снова выполнить
команду, поскольку просроченный request отклоняется. Идемпотентность живых receipts
сохранена. 34 fleet tests проходят, включая завершённые, активные и replay cases.
## Карта: ограничение текущего окружения
Канонический Core настроен на http://127.0.0.1:18103. На этом адресе нет listener;
/api/v1/map/gateway/health возвращает 502 map_gateway_unavailable. Поэтому live
приёмка тайлов/OSM buildings и записи cache пока не подтверждена. Новое окно
показывает недоступность и повтор загрузки, не обходит Gateway публичными tile URL.
Серверный shared Gateway уже поддерживает persistent live-tile-cache и отдельный
read-only offline-snapshot на NAS; это подтверждено source/compose, но не текущим
состоянием сервера. Docker/другой сервер в обход контура не запускался.
Итоговый Core apply: PID74340→85056, health accepted; plist identity сохранена.
Финальный readback: борт online, D455 streaming, X4 idle/preview0/recording0.
Acceptance report SHA256
6d51159c3eff97e19297c71cef40a57e391e2e7aacbac1ff0909cfdcfcea6922.
## Уточнение 10.09.2026: запуск X4 и фактический сервер карты
Предыдущая приёмка оставила X4 в idle, поэтому пользователь получил пустые окна.
В X4Observation добавлен «Начать просмотр» непосредственно в обоих окнах. Оба
действия используют один общий pending/ref guard и одну preview.start operation
для конкретной camera session; изображения по-прежнему обслуживает один peer.
Ошибки запуска показываются в тех же окнах. Закрытие окна не останавливает capture.
Start проверен через текущий GUI: один decoder 1280×640, оба canvas показывают
живые объективы, D455 продолжает работать. Финальный API: X4 online,
acquisition=streaming, preview=1, recording=0. Предпросмотр оставлен оператору.
Control Station typecheck/build проходят; Ubuntu/SDK не изменялись.
DCPLATFORM-61 подтвердил владельца карты: общий Platform Map Gateway на NAS,
а не отдельный Device Core cache. Read-only SSH health подтвердил service=ok,
ionConfigured=true, persistent readwrite cache: 71774 entries, 1519820206 bytes,
в том числе imagery/terrain/3D binary. Gateway слушает только NAS 127.0.0.1:18103.
Это проверка наличия cache, не новая визуальная приёмка карты или cold egress.
Подготовлен scripts/manage_map_gateway_link.py: локальный user LaunchAgent,
строго loopback 18103 → SSH → NAS loopback 18103, без remote command,
agent forwarding и provider credentials. StrictHostKeyChecking/BatchMode,
reconnect, exact SHA plan/apply, health gate, rollback и запрет занятого порта.
Три regression tests проверяют ограничение транспорта, устаревший plan и
откат первого неуспешного bootstrap.
Live apply не прошёл health gate: NAS /etc/ssh/sshd_config содержит глобальный
AllowTcpForwarding no; исключения есть только для root/admin, текущий account
не входит в них. SSH возвращает administratively prohibited. Проверенный
rollback удалил кандидат LaunchAgent; loaded=false, listener18103 отсутствует,
Core8000 healthy. Настройки NAS не изменены и запрет не обходился.
Следующий gate — разрешение администратора NAS на ограниченный local forwarding
для существующего account с PermitOpen=127.0.0.1:18103. Global forwarding,
reverse/dynamic forwarding и публикация Gateway в LAN/WAN не требуются.
После принятого изменения нужны sshd syntax/effective-policy checks,
повторный exact local plan/apply, same-origin health и визуальная приёмка
imagery/terrain/buildings с подтверждением NAS cache hits. До этого карта
считается недоступной; наличие серверного cache не закрывает её acceptance.
Private evidence SHA256:
9fef991a516ab516e7530c7c1b3cfb80056a619216d7d899ee67ea81ba44022b.
## Автоматическое наблюдение — уточнение владельца 10.09.2026
Открытие Центра означает запрос live-данных. Подготовленные online RealSense/X4
автоматически запускают preview; пользовательская кнопка нужна только при ошибке.
Уже активный capture/playback не перезапускается. RealSense использует driver-owned
default profiles с record=false. X4 использует preview.start. SDK preparation,
firmware, запись на БК/SD и запуск нового K1 project сюда не включены: K1 start
имеет отдельную семантику acquisition/recording с именем проекта, его существующий
активный поток подключается при открытии центра.
Shared observationStart/useObservationStart проверяют свежую inventory и exact
node/device/session перед действием, объединяют in-flight действия двух окон и
React remount, не повторяют неуспешный start бесконечно. Новая device session или
новое открытие разрешает новую попытку. Скрытые пользователем источники сохраняют
свой layout и не требуют нового peer до показа.
useSensorPreview различает оборванный viewer и подтверждённый stale source.
Viewer reconnect ограничен четырьмя попытками с backoff 2/4/8/16 s (включая
30 s expiry старого X4 peer после reload). Фоновая вкладка не объявляется source
failure из-за остановленного browser presentation. X4 при живой telemetry и
отсутствии кадров более 8 s восстанавливает preview.stop → preview.start,
только с подтверждённым recording=0. Stop failure или смена session не допускают
последующий START. Допускаются две последовательные попытки; бюджет сбрасывается
после 30 s live. Запись не останавливается и не запускается.
Live QA: воспроизведён исходный stale X4 при preview=1; новое окно самостоятельно
восстановило оба объектива. Затем штатными UI controls остановлены D455 и X4.
API перед открытием: обе idle, X4 preview=0/recording=0. Единственное действие —
«Центр наблюдения» — автоматически дало D455 RGB640×480 и два X4 canvas из одного
1280×640 decoder. Ручных start clicks=0. Повторный вход к активному capture
проверен. Final state: обе online/streaming, X4 preview=1/recording=0,
recording_active=false. Ubuntu runtime не менялся, Core8000 сохранён.
11 focused tests проходят: independent identities, no duplicate start,
active/playback preservation, stale/session rejection, preview-only recovery,
unknown/active recording guard, stop failure и replacement after stop; также
layout/blueprint tests. Control Station build/typecheck и Node UI typecheck passed.
Private acceptance SHA256:
c99c2e929618df21725ea1b8dcce08b242b6ab49f1b4b3b9cb5a125b1bad7124.
## OBS04: стабильность и доступ к карте — 10.09.2026
Уточнение заменяет прежний порог восстановления source: требуется 12 секунд
непрерывной stale telemetry, а не единственный устаревший снимок. RTP decoded
frames проверяются каждые 2 секунды независимо от callback рисования скрытого
X4 video. Последнее изображение сохраняется при задержке; ошибки peer и
отсутствие telemetry не перезапускают capture. SSE inventory имеет ограниченный
15-секундный grace с HTTP-проверкой. Старый Chrome frontend перезагружен.
Фактические DOM samples 17:27:49→17:52:39Z показывают рост media time обеих
камер без сброса. Итог: D455 640×480, X4 1280×640, обе ready4/unpaused.
838 frontend tests, focused20, оба typecheck и build passed. Уведомления
уменьшены на 30% до11.2px и используют безличные формулировки. Неисправный
Cesium canvas скрыт, поверхность карты остаётся полным чёрным прямоугольником.
Evidence SHA256 d885939be21b398970c41e5471d2580c0d10493f4dbff807bbdbe94790f64739.
Владелец разрешил только доступ к сервису карты. NAS доступен через Tailscale,
общий cache и AMD/VPN proxy здоровы. Подготовлен отдельный Platform component
mission-core-map-access: payload access.json, никаких ключей или файлов SSH
в пакете. Source commit11b73e64681f83aa2ebfd89ef266d3be2869f7e1. Candidate runner
f21936f131365bd3993e2d746e332538d628ba50ef62c1cce833161171ffde47; artifact
nodedc-mission-core-map-access-20260910-001.tgz SHA256
6904cbbc2809046ef47ae904571f86bfbec69e25b536c4e4e1a9fab55962fe50.
SMB staging подтверждён, lifecycle=staged. Live predecessor runner подтверждён
владельцем:8a43f7f945fc7fa79a4bc91ec91f15e39119e519b332dac450cf60e0681338cd.
Ожидаются отдельный root promotion, fresh plan/apply, затем local link apply
и визуальная приёмка карты. До этого карта не объявляется подключённой.
## Доступ карты применён — 10.09.2026, 17:56:41Z
Предыдущий pending gate закрыт. Владелец выполнил atomic root promotion и
verify-install с ожидаемым runner SHA f21936f1…, затем fresh plan и apply.
Runner завершил deploy-ok patch=mission-core-map-access-20260910-001; backup
mission-core-map-access-mission-core-map-access-20260910-001-20260910-205639.
SMB inspector подтвердил terminal_success/applied.jsonl line381 и совпадение
artifactSHA. Повторно применять или restage этот artifact нельзя.
Mac link применён из absent predecessor, loaded/healthy=true, listener только
127.0.0.1:18103. Core same-origin health ok; Cesium отображается в Центре рядом
с камерами. Все три provider подключились, fullscreen/restore и hide/restore
карты проверены. Cache inventory71774entries/1519820206bytes сохранён. Два
чтения terrain metadata:200,920353bytes,одинаковыйSHA,cacheStaleHits194→196,
egressRequests5→5. Это подтверждение чтения сохранённого cache.
Первоначальный отказ обновления provider был отдельным инцидентом AMD:
connector172.22.0.183:8791 возвращал ECONNREFUSED. Скриншот владельца показал
healthy container после недавнего запуска с правильным IP/port. После этого
terrain и buildings endpoints получили ion-endpoint-online за1.434s и0.584s.
NAS proxy pairing и directEgress=false не менялись. Новые ключи выдаются только
внутри NAS, browser видит credentialMode=gateway. Один контрольный health502
восстановился при следующем чтении; нулевой процент ошибок не заявляется.
Private deployment/product evidenceSHA 22f403608d7aca9cf38c070f171e8fa876a29d4224109d9a499d0b29663eb9c6.
## Финальная приёмка OBS04B
Cold cache fill подтверждён после восстановления AMD:24 новых objects зданий,
15161307bytes,cacheEntries71774→71798,новых upstream errors0. Все три слоя
Cesium подключены; серверный readwrite append-only cache сохраняется.
При разворачивании карты WebKit приостанавливал временно отсоединённый D455
video. previewPlayback возобновляет тот же stream без restart capture/peer;
пауза больше не отображается как live. Две дополнительные regression checks
и полный набор840tests/typechecks/build проходят. Map expand25s→restore
подтверждён на живом борту: обе камеры ready4/unpaused, media timestamps
продолжают расти. Подробности OBS04B installation ledger; evidenceSHA
b1d3c3c382866304ccac80e8cab9b49ca1a0ea5836af715baf96b9f3b4923ef9. Canonical Core8000 и map-link оставлены работающими.
## OBS05: компактные заголовки — 10.09.2026
По указанию владельца удалены отдельные строки «Прямой эфир» и повторная
подпись карты. Единственный StatusBadge variant=indicator находится сразу
после названия источника. Его цвет отражает исходное liveness-состояние,
а точное состояние доступно через aria-label и tooltip. Переходы подключения,
задержки и восстановления не объявляются зелёным live автоматически.
Выбор слоя RealSense перенесён к правым действиям заголовка. Кнопка «Слои
карты» открывает прежние switches imagery/terrain/buildings; дублирующая
шестерёнка у карты удалена. Согласованный glyph layers сначала добавлен в
Design Guideline Icon, registry, документацию и живой каталог. Геометрия
кнопок и индикаторов остаётся канонической.
BoardObservationCenter передаёт стабильные statusTarget/actionsTarget вместе
с media target. CameraObservation, X4Observation, K1Observation и карта
публикуют статус через ObservationHeader. Эти слоты не меняют владельца
capture, peer или renderer. Ошибки сохраняют доступное действие повтора в
заголовке; последнее изображение остаётся в media. Вся высота после шапки
принадлежит media, aspect ratio изображений сохранён через contain.
Проверены 4 architecture checks, оба UI typecheck, 840 frontend tests,
production build (app-mCmQLf6P.js), DG registry/icon check и catalog build.
Нормальный и развёрнутый центр проверены на живых D455/X4/Cesium; RGB →
глубина → RGB, окно слоёв карты, Escape. На ширине панели389px заголовок62px,
media326.5px, дополнительных body rows0, gap после заголовка0; статусная
точка отстоит от названия на8px. Длинные названия сокращаются с tooltip.
Во время подключения X4 был серый delayed/reconnecting, затем оба объектива
перешли в live; цвет не подменялся для визуальной приёмки.
После map expand/restore (18:41:04Z) все источники доступны, оба video
ready4/unpaused, gap0. Контроль18:42:33Z снова показал восстановление X4 при
сохранённом изображении; RealSense live и карта ready. OBS05 закрывает правки
интерфейса, но не доказывает непрерывность X4. Существующая preview recovery
не изменялась. Core8000 и Map Gateway health успешны.
## OBS06: настройки окон и перенос всей панели — 10.09.2026
Выбор позиции каждого окна занимает50% ширины общей формы, независимо от
длины названия. Проверено на семи источниках после появления K1:
верхнее поле523.21875px, каждый select261.609375px. Слои карты содержат
только три переключателя; технические пояснения и лишний health polling
этого окна удалены. Сам Gateway, серверный cache и настройки egress не менялись.
В Design Guideline исправлен общий Switch: включённый бегунок использует
on-accent, выключенный track следует тону темы, track не сжимается из-за
подписи. В Mission Core checked track rgb(247,248,244), thumb rgb(8,8,10),
ширина32px; выключенное состояние визуально различимо. Обновлены canonical
styles.css, registry/components.json, docs/COMPONENTS.md и catalog specimen.
DraggableItem охватывает GlassSurface с заголовком и живым media target.
DragHandle остаётся единственным инициатором. Временно раскрывается overflow
только у веток SplitPane с активным переносом; медиа не клонируется и не
перезапускается. Mid-drag DOM samples на конечной сборке подтверждают
одинаковые headerX/mediaX при dx49/73/97px и gap0. Drop переставляет весь
источник; исходный порядок восстановлен. После появления семи окон
добавлен перенос действий в панелях <=340px; названия больше не вытесняются
кнопками. В широкой панели778.625px сохраняется один header высотой62px.
Проверки: architecture4/4, оба UI typecheck, frontend840/840, production build
app-Lo_50rZQ.js, DG registry validation и catalog build. Live QA: форма из7
строк, map OSM off/on с восстановлением, оба направления drag с media,
обычный/развёрнутый центр, отдельная широкая панель и Escape. Финальный
DOM18:59:15Z: обе камеры ready4/unpaused, media50.057s/50.081s, dragging0.
K1 обнаружен, три его viewport доступны, acquisition не запускался этой
правкой. Runtime БК, SDK, запись и capture policy не менялись.