# Архитектура дома СИНГУЛЯР — комод: ящики → мост → вещи

> **Статус:** ✅ Актуально · **Такт:** v10.59 «СИНТЕЗ» · **Обновлено:** 2026-10-11
> Объяснение «почему так». Пошаговые действия — в [РИТУАЛ_ТАКТА.md](РИТУАЛ_ТАКТА.md); сухие факты о дверях — в `data/versions.json`. См. также: [adr/](adr/) — почему принято каждое решение.

## Главная идея

Дом — один сайт без сборщика, без сервера, без зависимостей. Вся логика живёт в браузере жильца. Чтобы десятки комнат (HTML-лиц) не грызли друг друга глобалями, дом устроен как **комод**: у каждой семьи функций свой **ящик**, наружу семья выходит через **мост**, и в комнате её вещи лежат как обычные глобали.

```
ящик (script-блок, изолированный) ──мост──▶ вещь (window.__Х)
   С23 синхро·пульс·синхрон                  delete window.X
   С24 голос·микрофон                        Object.defineProperty(window, X,
   С25 ЛАБ·виз·движение                         {value, writable:false})
   С26 сцена·свет
   С27 склад·сканер
   С28 пульт·сообщения      мосты = вещи (живые числа — в КАЗНЕ дома, ПУЛЬТ → паспорт)
   С29 ЛАДОМ (пульт вечера)
   С30 слово·профиль (__ХАРМ, __ПРОФИЛЬ)
   С39 колонка·трек (window.КОЛОНКА)
   __КОМОД — общий шкаф на window
```

**Мост** (`delete` + `defineProperty`) делает три вещи: стирает старую копию глобали, закрепляет новую как неизменяемую (writable:false), и держит порядок переселения — ни одна строка логики дома не переписана, все семьи переехали как есть. Логика моста проверяется тестом [ИНСТРУМЕНТЫ/test_bridge_logic.js](../ИНСТРУМЕНТЫ/test_bridge_logic.js).

## Лица дома

- **Хаб ·00** (`index.html`) — кристалл на пьедестале: живой холст (WebGL, ноль картинок), осколки-двери, нить Ариадны (все двери реестра — 31), поиск АРИАДНА (намерение словами → дверь, Левенштейн), НАМЕРЕНИЕ «Я сам», меню дома.
- **31 дверь** (`СИНГУЛЯР_NN_ИМЯ.html`) — комнаты: хор (·15–·18), человек (·19–·21), связь и автономия (·22–·26), рельсы (·27–·30), зал и сцена (·31–·34), помощь (·35–·37), здоровье и организм (·38–·39), треки-братья (·40 ГАРМОНИЯ, ·41 НАМЕРЕНИЕ, ·42 КОЛОНКА).
- **Манифест ядра** (`singulyar-modules.js`, `SNG.модуль`, v1.20.0) — единственный источник истины о дверях и нитях: хаб + 31 дверь, связи симметричны.
- **Летопись** (`data/versions.json`) — версия, такт, дата, счётчики, двери, AI-модели.

## Ядро и движки

- `singulyar-modules.js` — ядро SNG: кристалл, осколки, живая нить (связи дверей + память пути), карта.
- `singulyar-ux-engine-v9.js` — UX-движок: справки при наведении, меню дома (полная навигация по дверям, собирается заново при каждом открытии), перетаскивание, доступность, оси звук/голос/тема/роли.
- `singulyar-design-v3.css` — дизайн-система: void #0A0A0C + стекло + канонное золото #D4AF37 (тёплое #A67C00 на светлом); темы; `prefers-reduced-motion`.
- `sw15.js` — сервис-воркер: cache-first, поколение `s15-orkestrator-vNN`, потолок кэша, ядро офлайна неприкасаемо при вытеснении, страховочная оболочка (навигация без кэша → index.html).
- `cord.js` — страховочный КОРД: нить порвалась — дом держит (панель «Нить порвалась», журнал сбоев, тихий режим).

## Память

Всё состояние — в `localStorage` ключами `kv.*`: роли жильца, последний вид пульта (`kv.pult`), последние команды (`kv.pult.команда`), визиты, хотелки. Хранилище огорожено гардом (порченый JSON не валит дом). Ключи шифрования и биометрия никогда не покидают устройство.

## Мозги на устройстве (приватность в железе)

- **Малыш-LLM** (·21 ОБЩЕНИЕ): Qwen2.5-0.5B-Instruct q4_k_m через wllama (wasm), 6 частей кэша `singular-llm-parts-v1`, правила доучиваются с апстрима `rtynbirf/singulyar-llm` (кэш `singular-llm-rules-v1`). Слова жильца не уходят в сеть.
- **Слух**: Whisper (tiny/base/small) через @huggingface/transformers — тоже локально; прогрев по умолчанию — tiny.

## Кэш-поколения (почему номер обязателен)

Service worker живёт cache-first: если выкатить новый код и не поднять поколение `s15-orkestrator-vNN`, жилец увидит старое — и «правка не работает». Канон такта: **любой такт трогает sw15.js и поднимает поколение** (v108 → v109 в «АТЛАСЕ»); новые активы вносятся в пре-кэш; `data/versions.json` получает запись такта.

## CSP и инлайн-скрипты (шрамы v10.52 и v10.54)

`<meta Content-Security-Policy>` без `'unsafe-inline'` молча убивает все инлайн-скрипты страницы; консоль не ругается, половина дома «не кликается» (шрам v10.52). Диагноз ставится событием `securitypolicyviolation`; мету правим цельным текстом, не regex-кусочками. **Шрам v10.54 добавил ещё два молчаливых убийцы CSP**, найденных vm-тестом на всех 38 лицах дома:

1. **Текст вне комментария внутри `<head>`** (например «страховочный корд…») — любой не-пустой текст выталкивает парсер из head в body; CSP-мета, charset и og-теги уходят в body, и браузер молча ИГНОРИРУЕТ всю политику. Страдали 31 лицо.
2. **Хэш без кавычек** (`sha256-…` вместо `'sha256-…'`) — по грамматике CSP3 invalid source; политика «жива», но хэши не работают, инлайн-блоки блокируются.

**Канон постур А** (как на хабе и ЛАДОМЕ): `script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' blob:` + внешние hosts при надобности; без хэшей — пиннинг требует перехэширования при каждой правке инлайна и молча ломает лицо (дорога вернёт хэши только с авто-штампом в такт-цехе). `'wasm-unsafe-eval'` обязателен: мозги Малыша (wllama) и слух (transformers.js) живут на WASM. Итог v10.54: CSP жива и одинакова на всех лицах дома. Подробнее: [adr/0002-мост-delete-defineproperty.md](adr/0002-мост-delete-defineproperty.md), летопись тактов v10.52/v10.54.

## Треки — братья

СИНГУЛЯР_01/02 (и следующие треки) — самодостаточные однофайловые платформы, входящие домом полноправными дверями через АРИАДНУ. Горн-протокол: байты трека принимаются или резкуются, решение фиксируется в летописи. Ноль изображений там, где всё рисуется кодом.

## Соседи

- [ТЗ.md](ТЗ.md) · [ДОРОЖНАЯ_КАРТА.md](ДОРОЖНАЯ_КАРТА.md) · [РИТУАЛ_ТАКТА.md](РИТУАЛ_ТАКТА.md) · [МАЛЫШ.md](МАЛЫШ.md) · [adr/](adr/) · [ДОКУМЕНТЫ/АРХИТЕКТУРА_МОДУЛЕЙ.md](../ДОКУМЕНТЫ/АРХИТЕКТУРА_МОДУЛЕЙ.md) — карта модулей ранней эпохи · [ДОКУМЕНТЫ/СВОД_ЗАКОНОВ.md](../ДОКУМЕНТЫ/СВОД_ЗАКОНОВ.md)
