docs(hygiene): ARCHITECTURE.md — карта, а не хроника (#680)

Волна 3 эпика #674. ARCHITECTURE.md 2330 → 653 строки: система координат
прототипа 1489×1053, разделы Hidden Isometric Stage 2/4 (текущее — ISOMETRIC.md,
история — ADR 122/570), хроники «Additions v1.28–v1.41» и «Audit follow-ups»
сняты; подсистемы — короткое описание со ссылкой на канонический документ.
Устаревшее исправлено по коду: дерево Layout (store.py, frontend_registration,
весь список модулей), хранилища (config, layout, virtual_lights, trails),
ленивые локали de и fr, таблица WS API (31 + 3 команды, #256-проекция,
space/delete, files/cleanup без keep, контент через /api/houseplan/content),
DevItem без несуществующих полей, отказ help/feedback по support_api.

Всё ещё верное и не записанное в другом месте перенесено в канонические
документы: DEVICE-PRESENTATION (заметки реализации, Action authority, черновик
диалога), RADAR (карта реализации), VACUUM (владение кодом), CANVAS (icon_size,
--hp-cell-visual-scale, барьер записи координат), FILTERING (#44, каталог),
DECOR-EDITOR §7 (инварианты бэкенда ассетов), WALL-THICKNESS (§1 идентичность
и нулевые стены, §2 кэши, §4 hover/туннели/острова, §6 удаление комнаты,
§9 failed-core, §11 завершение цепочки и комната по грани), ISOMETRIC
(isoPlaneMatrix, iso-overlays, створки, служебные атрибуты), LIGHT (Glow над
заливкой #55, формула и screen-смешение), CONFIG-COMPATIBILITY (манифест схемы
#33, Masonry-слоты #561, квадратный холст v1.48, устаревшие URL контента,
layout/set #356), SCOPE (таблица владельцев при сборке файлов), WARM-REMOUNT
§5 (холодная загрузка и визуальная непрерывность), UX-MODES (порядок
стартового пространства), PDF-EXPORT (граница реализации), FURNITURE (adopt,
BOOT_MAX_MS). Раздел TESTING «Backend quality gates (#42)» и строка
DEVELOPMENT о bundle-freshness — из того же разбора, в предыдущем коммите.

Issue: #680
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
Claude
2026-09-27 22:33:04 +03:00
parent 696f5a789f
commit 4bc3e9baa6
16 changed files with 977 additions and 2231 deletions
+29
View File
@@ -229,6 +229,35 @@ successful config change, so an interrupted browser-side cleanup is repaired.
An initial position sampled during integration startup follows the same
debounced persistence and live-update path as a later state event.
## Code ownership
- `src/vacuum-routes.ts` is the only answer to "which map is on which floor":
`effectiveRoutes()` (explicit `map_routes`, or the legacy `calibration`
dictionary as routes into the dock's space) and `resolveRoute()` (the six
results above, never a guess). The result is computed once per frame into
`render-device-snapshot.ts` (`facts.get('vacuum:<id>')`) so `render()` cannot
derive a second answer; `planVacuumOverlay()` decides what the visible space
draws.
- Route editing lives only in the lazy editor graph (`vacuum-route-edit.ts`,
`editors/vacuum-maps-section.ts`); the View card never loads it.
- `custom_components/houseplan/vacuum_routes.py` mirrors the resolver and the
legacy-run adoption rule byte for byte, driven by `test/fixtures/vacuum-routes/`;
a divergence shows up as a robot on the wrong floor.
- `src/vacuum.ts` owns pure normalization/arbitration: paths are always
`Pt[][]`; `resolveCurrentVacPath()` is the only integration → server → local
decision; `resolveVacSource()` pins saved sources and limits automatic
selection to compatible same-device entities; the card adds registry status
through `resolveHaBindingStatus()`.
- `smoothVacPath()` takes calibrated flat plan coordinates and returns typed
`move|line|quadratic` commands for a caller-supplied physical radius; the card
then projects (flat/2.5D) and serializes. Each corner is a quadratic inside the
adjacent-segment convex hull, bounded by half of both segment lengths, which
makes the 17.5 cm limit, exact endpoints and subpath gaps structural.
- Auto-calibration uses the same shoelace `areaCentroid()` for plan polygons and
robot outlines; residuals go through resolved grid pitch and `cell_cm`.
`trails.py` owns current/previous runs and the refresh-time `(marker, source)`
health state.
## Troubleshooting
1. Open the vacuum's device settings and read the source diagnostics.