# ОТЧЁТ_ПОЛНЫЙ — вселенная СИНГУЛЯР RUVSON

Дата: 2026-10-02 · состояние: **v1.7 ОС / ·15 v1.1 / всё протестировано; репозиторий GitHub на 100 %, релиз v1.7 создан, сайт GitHub Pages включается одной авторизацией**

---

## 0. Резюме (20 секунд)

Собрана и выведена в рабочее состояние офлайн-вселенная караоке канала RUVSON:
**61 песня канала + флагман «Когда теряем» (OutShadow feat RUVSON), 158 языков,
24 759 языковых дорожек-пар, 13 модулей в одной оболочке, PWA-хостинг на GitHub Pages.**
Каждое число вычисляется из данных (CLAIM → EVIDENCE), каждый пункт внешней
ревизии закрыт кодом и тестом или честно помечен как будущая работа.
Тесты: **53/53** модуль ·15, **44/44** ОС. Внешних сетевых запросов: **0**.

---

## 1. Хронология: что сделано

### Этап 1 — Каталог канала
- Собран полный список **61 видео** канала @ruvson_music (UC_ttWy-FkkslIosKf6Eyqgg) парсером ytInitialData + Innertube continuation (адаптация к новому формату lockupViewModel).
- Даты уточнены по официальному RSS-фиду.
- Итог: **10 182 300 просмотров**, общая длительность **5 ч 47 мин**, топ-ролик «Цени время» — 2,5 млн.
- Каталог собран в песочнице агента (xlsx 2 листа, DataBar, ссылки — в дом не вынесен, вес); факты каталога — в этой сводке и в титул-корпусе ·01.

### Этап 2 — Флагман и материалы
- Для «Когда теряем» (rWpYxmFjm9g, OutShadow feat RUVSON): превью, **SRT**, транскрипт, thumbnail, мастер-аудио (длительность 230.883 с по ffprobe).
- Собраны **157 официальных переводов YouTube** (srt + txt + индекс): `ДАННЫЕ/флагман_157_языков/`.

### Этап 3 — Тексты и многоязычный корпус
- Тексты всех 61 песни: srt/lrc/txt — `ДАННЫЕ/RUVSON_ТЕКСТЫ_61_песен_srt_lrc_txt.zip`.
- Корпус LRC на языки — `ДАННЫЕ/RUVSON_МНОГОЯЗЫЧНЫЙ_КОРПУС_LRC.zip` + `ИНДЕКС_МУЛЬТИЯЗЫК.md`.
- LLM-конвейер переводов (демон): **228 дорожек в паке** из целевых 793 (61×13), восточные языки в работе.

### Этап 4 — Платформа СИНГУЛЯР_01 (флагман ×157 голосов)
- Автономный HTML 15 МБ: караоке с реальными ASR-таймингами ru + 157 YouTube-дорожками, минусовка ДНК, 3 вшитых трека.

### Этап 5 — СИНГУЛЯР_02 «ФАБРИКА»
- Эмерджентная архитектура 7.7 МБ: генерация песен, конвейер, слушалка, караоке-колесо.

### Этап 6 — СИНГУЛЯР·ОС (единая оболочка)
- v1.4 (11 модулей) → v1.5 (12) → v1.6 (13: +ОРКЕСТРАТОР) → **v1.7 (модуль ·15 v1.1)**.
- Модули: ПЛАТФОРМА, ФАБРИКА, RUNTIME, ГЕНОМ, ПЕСОЧНИЦА, КОНТРАКТ, SWARM, СЛОВАРЬ ГИПОТЕЗ, СЛОВАРЬ С МОДЕЛЬЮ, ЕДИНОЕ ЯДРО, КАРАОКЕ-СТУДИЯ, ЭМЕРДЖЕНТНОСТЬ, **ОРКЕСТРАТОР ·15**.
- Один файл 40 МБ, 0 внешних запросов, конвейер 01→15, менеджер загрузки.

### Этап 7 — Внешняя ревизия ·14 ХОР (файл с Диска, 1656 строк, MD5 `0a88dcc5…`)
- Прочитана **полностью**, сведена в реестр: Часть 1 — дефекты D1–D6; Часть 2 — топ-20 потребностей; Часть 3 — практики 2026 (M1–M6).
- **D1** «по 12» ≠ код → проб минусовок реально батчами по 12 с паузой 900 мс.
- **D2** «×157» зашито → вычисляется из данных (`Object.keys(flag.yt).length`).
- **D3** магия «/61» → все счётчики вычисляются (computeCounts).
- **D4** тихий пустой PACK14 → пак вшит; сбой → баннер «РЕЕСТР НЕ ЗАГРУЖЕН» + стоп, типовые коды S15_PACK_*.
- **D5** DOM-XSS через innerHTML → **ноль innerHTML** (assert сборки + тест), всё через DOM API.
- **D6** недоказанная локальность → assert: нет fetch/XHR/WebSocket/sendBeacon; внешних запросов 0.

### Этап 8 — СИНГУЛЯР·15 «ОРКЕСТРАТОР» (ответ на топ-20)
Четыре ядра: **CONTENT** (модель song/track/line/word + реестр происхождения: verified / machine-draft / user-import, версии) · **TIMELINE** (нормализованный таймлайн, слово-уровень, интерполяция помечена `interp`, строгий валидатор: NaN/отрицательные/монотонность/дубли/провалы>20 с/выход за длительность) · **AUDIO** (мастер-часы audio.currentTime → rAF; шина: тишиной-часы + зацикленный буфер, рендер 0.3 с вместо 27 с; state machine idle→loading→ready→playing⇄paused→error; autoplay: NotAllowedError → S15_AUTOPLAY_BLOCKED; Media Session) · **ACCESSIBILITY** (RTL ar/he/fa/ur, aria-live «не смотреть», клавиатура, крупный текст, prefers-contrast, prefers-reduced-motion).
Импорт LRC/SRT/VTT/TXT со строгой валидацией ДО сортировки; экспорт LRC/WebVTT (караоке-теги)/JSON; IndexedDB-память минусовок; АУДИТ каталога (сводка + 62 карточки); РОДОСЛОВНАЯ ·10→·15.

### Этап 9 — Интеграция практик 2026 (·15 v1.1)
- **Темп ×0.50–1.50**: playbackRate + preservesPitch + синхронный WebAudio-луп.
- **Тональность ±6 пт**: detune в синтез-режиме (для файлов честно: нужен AudioWorklet).
- **PWA**: при https-хостинге — манифест + регистрация `sw15.js` (cache-first, минусовки сеть→кэш); на file:// не притворяется.
- **Крупный текст** (aria-pressed) + **prefers-contrast**.
- Скоринг пения — **осознанно отсутствует**: в минусовке нет эталонной мелодии, оценивать нечестно. Есть монитор тональности/уровня + реверб.

### Этап 10 — Хостинг (GitHub, проверено побайтово)
- Репозиторий **github.com/rtynbirf/singulyar** (public): ядро, платформа ×157, фабрика, ·15, все ДАННЫЕ (каталог, тексты 61, корпус LRC, 157×srt + 157×txt флагмана, индексы), ИНСТРУМЕНТЫ (Grabber, УСТАНОВЩИК), ДОКУМЕНТЫ (5), СКРИНШОТЫ (40), PWA-слой (sw15.js, manifest, icons, .nojekyll).
- Загрузка шла веб-протоколом GitHub (manifest → policy → S3 → completion → commit) с чанкингом по 100 файлов; лимиты сервера: 25 МБ/файл, 100 файлов/манифест.
- Каждый ключевой файл проверен анонимным `raw.githubusercontent.com` → HTTP 200; полная сверка деревьев `site/` ↔ репо: расхождение 0.
- **Релиз v1.7** создан (id 401219726) — для файла ОС 40 МБ, который не проходит лимит 25 МБ: `releases/download/v1.7/СИНГУЛЯР_ОС_v17_13_МОДУЛЕЙ.html`.
- **GitHub Pages** (`https://rtynbirf.github.io/singulyar/`): включается через device-flow токен (автоматически) или вручную — Settings → Pages → Deploy from a branch → main / root → Save.

### Этап 11 — P2P-ЗАЛ ·17 + FUSION ·16 (по ТЗ KARAOKE_TREND.txt) — v1.7
- **·17 ЗАЛ**: BroadcastChannel-экран зала (дедуп src:seq, localStorage-фолбэк), пульт CMD (play/pause/stop/±5 с),
  air-gapped WebRTC: свой QR-энкодер (ECC L, v1–40, 0 зависимостей, таблицы сверены с python-qrcode 40/40),
  sdPack SQ0/SQ1/SQ2, телефон-микрофон (McLeod MPM в worklet, 15 Гц) + пульт.
- **·16 СУФЛЁР v1.1 / Fusion**: SingulyarUltraStarAssembler — слова ASR × ноты DSP (привязка ±0,6 с,
  мелизмы «~», «♪» непривязанным, квант 1/16 бита, паузы >1,5 с → новая строка) → UltraStar .txt в память notecharts.
- **Фикс косяка**: пульт seek двигал ±1 с вместо ±5 с — HallTransport.send() перезаписывал поле `v` (версия)
  значением seek; протокол переведён на `ver:1` + отдельное поле `v`.
- Тесты: логика 18/18 (Fusion roundtrip, SDP SQ0/SQ1, QR == эталон v1/v5/v10/v17); браузер 21/21 Playwright.

### Этап 12 — СОБЫТИЕ ·18: SOCIAL CORE «СОВМЕСТНОЕ ПЕНИЕ / ПАМЯТЬ» — v1.8

Требование (ТЗ хозяина): превратить одиночное караоке в **СОБЫТИЕ** — комната без аккаунтов,
участники со своих устройств, живые голоса, общая запись, временная память с осознанным сохранением.
LOCAL CORE (офлайн-ядро) не переписывался — соц-слой включается по желанию и без интернета ничего не ломает.

| CLAIM | CODE | TEST | РЕЗУЛЬТАТ |
|---|---|---|---|
| ROOM: LOBBY→READY→COUNTDOWN→SINGING→FINISH→REVIEW, хост-авторитет, миграция хоста | `КОМНАТА` в ·18 (replicated state, seq, снимки) | логика: машина фаз 9/9 + симуляция хост+гость 13/13; браузер: полный цикл | ✓ |
| Анонимные участники (имя+эмодзи, без email/password), слушатель равноправен | HI/READY/SGG/DN/BYE, нормИмя | браузер: вход по коду из QR, чипы, готовность | ✓ |
| Синхронный старт «3-2-1-🎵» | ping/pong clock-offset (медиана, фильтр RTT), startAt от хоста | логика: offset ±250 мс восстановлен, мусорный RTT отфильтрован | ✓ |
| Голоса между устройствами без сервера (MediaTransport) | ТРАНСПОРТ_РЕТРАНСЛЯТОР (trystero/nostr, вендино) + ТРАНСПОРТ_КАНАЛ (BroadcastChannel+WebRTC) | браузер: полный цикл по каналу 20/20; реле: 2 окна соединились через публичные Nostr-реле | ✓ |
| Запись события у каждого (голоса+минусовка) | WebAudio-граф (без самопрослушки) + MediaRecorder → IndexedDB | браузер: blob >1 КБ у хоста и гостя | ✓ |
| TEMPORARY 7 дней → ❤️ ПАМЯТЬ (человек решает сам) | ХРАНИЛИЩЕ.gc, карточки, фото 640px, подпись, экспорт webm | браузер: ❤️ → MEMORY; GC стёр просрочку (1), память пережила | ✓ |
| «МОИ ВОСПОМИНАНИЯ» как главный экран | карточки на меню + экран #память | браузер: карточка в списке после сохранения | ✓ |
| Приватность: запись не покидает устройства | нет ни одного upload-пути в коде; манифест события локален | аудит кода; манifест/политика памяти в манифесте | ✓ |

**Косяки, пойманные и исправленные по пути:**
1. `index.html`: карточка ·17 была вставлена ПЕРЕД `<!DOCTYPE` и разорвала доктайп (quirks mode на живом сайте) —
   исправлено, карточка вернулась в сетку, добавлены главные кнопки «СПЕТЬ ОДНОМУ / СПЕТЬ ВМЕСТЕ /
   МОИ ВОСПОМИНАНИЯ / ПЕСНИ».
2. Протокол КОМНАТЫ: исходящие сообщения не несли `ver`, входящие её требовали — вся связь молча бы
   отбрасывалась (поймано мок-тестом до браузера) → единый `отослать()` ставит версию.
3. Гонка HI: гость шлёт HI до открытия DataChannel → хост не узнаёт об участнике → ретрай HI до включения
   в снимок + перевещание снимка при новом пире (поймано реле-дебагом) ✓.
4. Хост не видел свой отсчёт (startAt назначался после перехода фазы) → порядок исправлен.
5. Гостям не грузилась минусовка (src ставил только хост) → preload у всех в onСостояние.
6. API trystero 0.25: `onPeerJoin` — свойство, makeAction возвращает объект — транспорт переписан;
   явные реле + STUN в rtcConfig.
7. REVIEW не открывался (локальнаяФаза молчит) → прямой показ экрана после финализации записи.
8. Каталог: флагман `rWpYxmFjm9g` вне мультиязык-индекса получал ID вместо названия → специальный title;
   дубли названий дизамбигуированы.

**Честные границы ·18 (не притворяемся):** mesh-топология до ~4–5 участников (дальше SFU — дорожная карта);
TURN-релея нет (жёсткий симметричный NAT может не пробиться); записи живут локально у каждого — серверной
памяти нет (осознанно); сигналинг идёт через публичные реле (медиа — всегда P2P/DTLS).

---

### Этап 13 — ЧЕЛОВЕК ·19: Human-First + SINGULAR SERVER v1 + пересборка OS_v18 — v1.9

Вход: прототип SINGULYAR_HUMAN_FIRST_v2 (идентичность/Friends/Adaptation) + ТЗ «СОБЫТИЕ/СОВМЕСТНОЕ ПЕНИЕ/ПАМЯТЬ».

| CLAIM | CODE | TEST | RESULT |
|---|---|---|---|
| Прототип: «server syntax OK, tests 5/5» | аудит архива | node --check + node --test | синтакс OK, 5/5 подтверждены, но 2 из 5 — тавтологии (константы), авторизация не тестировалась вовсе |
| Авторизация личностью работает | server.mjs + ·19 | тест webcrypto→crypto.verify | КОСЯК №1 ПРОТОТИПА: WebCrypto даёт ECDSA в raw IEEE P1363, сервер ждал DER → каждая настоящая подпись получала 401. Исправлено (`dsaEncoding: "ieee-p1363"`), инвариант 12/12 |
| Приглашение доходит | server.mjs | WS-тест | КОСЯК №2 ПРОТОТИПА: сообщение при офлайн-получателе терялось (класс «HI-гонки» ·18). Добавлена очередь живых событий (сутки) с флашем при подключении |
| Связь можно восстановить | server.mjs | переходы состояний | КОСЯК №3 ПРОТОТИПА: после remove запрос дружбы молча не работал (state «removed» не сбрасывался). Исправлено + добавлены decline/block, kick ≠ разрыв дружбы проверен переходом, не константой |
| TTL временных записей по ТЗ | server.mjs | тест значений | 7 дней (прототип давал 1 час), лимиты аплоада добавлены (прототип не ограничивал) |
| GC стирает всё просроченное | server.mjs | ИНТЕГРАЦИОННЫЙ ТЕСТ ТЗ | CREATE→TEMPORARY→EXPIRE→GC→метаданные absent + блоб absent — PASS |
| ·19 не ломает офлайн-ядро | СИНГУЛЯР_19_ЧЕЛОВЕК.html | vm-синтаксис, 0 innerHTML, алфавит кодов == ·18 | 40 КБ, standalone, сервер опционален |
| Мост «позвать спеть» → зал | патч ·18 `?хост=КОД` | статические проверки + 55/55 логики ·18 | ведущий создаёт зал с кодом из приглашения; клик-обработчик защищён от MouseEvent-как-кода |
| ОС v1.8 «17 модулей» | build_os_v18.py | 17 записей, b64 байт-в-байт, ORDER/BOOT/JSON-LD | SINGULYAR_OS_v18_17_MODULES.html (42.3 МБ) |
| Тесты не врут | test_s19_human.js | node --test | 12/12 (инварианты + живой сервер на случайном порту) |

UNKNOWN (честно): реальный Web Push в фоне (iOS/Android), TURN за симметричным NAT, VoiceOver/TalkBack
на живом ·19, три телефона в одной комнате, нагрузка сервера, перенос личности на новое устройство
(non-exportable — ключ не переезжает), SQLite под нагрузкой (сейчас JSON с атомарной записью),
SFU для >5 участников.

### Этап 14 — ФОНЕТИКА ·20: Local Phonetic Guide / Vocal Guide — v1.10

Вход: ТЗ KARAOKE_TREND, лакуна №3 «Фонетический подсказчик и вокальный гид» + строка 507
(«транслитерация встроенными таблицами или anyascii — одна небольшая зависимость, вписывается в монолит;
Web Speech API / лёгкий WASM-модуль»).

| CLAIM | CODE | TEST | RESULT |
|---|---|---|---|
| Офлайн-романизация всех 158 языков | вендин any-ascii 0.3.3 (ISC) → `БИБЛИОТЕКИ/any-ascii.bundle.mjs` (esbuild, 534 КБ, динамический import как в ·18) | смоук против бандла: ru/zh/ja/ko/hi/ar/el/he/th/ka/hy/am | каждый скрипт даёт латиницу; «одна небольшая зависимость» подтверждена |
| Слоги для пения | ядро ·20: прогоны Unicode (han/kana/hangul/other), капитальный сплит для han/hangul, кластеры каны (малые + ー) | тест поймал косяк: на стыке прогонов не было пробела (「konnichihashi jie」) → добавлен пробел на границе ЦЗЖ-прогонов; регрессия 51/51 | こんにちは世界 → konnichiha shi jie; 우리가 → u li ga; 私 → si |
| Язык TTS из текста | детект скрипта → BCP-47; кириллица-эвристика uk(їєґ)/be(ў)/sr(ћђ)/kk(әғқ…); han/kana эвристика ja/zh | 18 языковых кейсов + latin→null | ru/uk/be/sr/zh/ja/ko/hi/ar/el/th/he/hy/ka/am различаются; override 38 языков |
| Произношение без сети | Web Speech API: голос точный → префикс → дефолт; честный статус если голоса нет; 🐢 rate 0.55 | Playwright headless (без голосов): тап по чипу не падает, статус честный | локальные голоса ОС; сетевых запросов нет |
| Фонетика поверх поющей песни | мост «СУФЛЁР ·16»: только-слушатель STATE ver:1 (word/next/song) по singulyar-hall; BC + localStorage-фолбэк + разовый опрос свежего ключа | Playwright: STATE → слово/романизация/«далее»/aria-live; мусор (CMD/ver2/без-word) отфильтрован; 0 ошибок консоли | ядро ·16 НЕ тронуто (0 правок) |
| Тесты не врут | `ИНСТРУМЕНТЫ/test_s20_logic.js` (51), `ИНСТРУМЕНТЫ/test_s20_browser.py` (28) | node + Playwright | логика 51/51, браузер 28/28; регрессия ·16 5/5, ·17, ·18 55/55, ·19 зелёные |
| Инфраструктура тестов живёт | КОСЯК СРЕДЫ: python `http.server` в песочнице виснет (обработчик пишет в мёртвый пайп после смерти родителя с capture_output) — соединение принимается, ответа нет | curl-диагностика + node-сервер | `ИНСТРУМЕНТЫ/serve_repo.mjs` (node, traversal-защита, MIME) — браузерные тесты ·18 и ·20 переведены на него |

UNKNOWN (честно): тоны пиньиня (любая романизация хань без диакритики), IPA (выбрана романизация по ТЗ),
качество арабского/иврита без огласовок, хангыль без сандхи-слияний (an nyeong, не annyaeng), малая цу
аппроксимирована (きっぷ → kitpu), TTS-голоса зависят от ОС (158 локальных голосов не существует),
живые телефоны (headless-хром без голосов), WASM-нейро-TTS — дорожная карта.

### Этап 15 — ОБЩЕНИЕ ·21: чистка прототипа «Human Communication v0.2.0» и интеграция — v1.11

Вход: архив `singulyar-human-communication-prototype-0.2.0.zip` (8 файлов) + директива: «УБЕРИ ВЕСЬ ХЛАМ,
ОН К ПРОЕКТУ НЕ ОТНОСИТСЯ, НИКАКИХ ЯРЛЫКОВ НА ИНСТРУМЕНТЕ — ТОЛЬКО ЧЁТКОЕ И ГРАМОТНОЕ ОБОЗНАЧЕНИЕ ВСЕХ И ВСЯ».

| CLAIM | CODE | TEST | RESULT |
|---|---|---|---|
| В архиве нет постороннего хлама | удалён осиротевший `manifest.json` (не подключался к странице, не валидный PWA-манифест, англ. поле «claims»); убран JSON-дамп состояния `<pre id="state">` из интерфейса | тест: `id="state"` отсутствует, `manifest.json` не упоминается | инструмент показывает только то, что нужно человеку |
| На инструменте нет ярлыков | «Human Communication Prototype» → «ОБЩЕНИЕ ·21»; «IN:/OUT:» → «Принимает:/Выводит:»; «status=created» → «показано»; «· local» → «· на устройстве»; «Speech Synthesis недоступен» → «Озвучивание недоступно»; участники «Человек A/B/C» → «Человек А/Б/В»; сырые коды `any/female` в отрисовке → «любой/женский» | браузерный тест: в отрисовке нет сырых кодов, все органы управления подписаны по-русски (54/54) | чёткие и грамотные обозначения всех и вся |
| Функциональность 0.2.0 сохранена без потерь | маршрутизация представлений (текст/Брайль/речь/вибро), персонализация голоса (голос устройства, язык, темп, высота, громкость, 4 профиля + «Мои настройки») перенесены 1:1 | логика 54/54 + браузер 32/32 (Playwright): маршруты, профили, сохранение, перезагрузка, сброс | всё, что заявлено 0.2.0, работает в 0.2.1 |
| Проектная дисциплина | интерфейс переведён на DOM-фабрику: 0 `innerHTML` (в v0.2.0 было 5 использований); ядро вынесено в чистые функции с маркерами S21:CORE | тест достаёт ядро из ОТГРУЖЕННОГО файла и исполняет (не копия); `\.innerHTML` не встречается | тесты проверяют ровно тот код, что у людей |
| Смысл ≠ представление (инвариант) | `route(person, text)` строит представления по `output[]` получателя; голос копируется без мутации профиля | инвариант смысла: текст/речь дословно, Брайль согласован с ядром; мутация копии не трогает профиль | сообщение остаётся тем же сообщением в любом канале |
| Честность вместо притворства | «создано → доставлено» (в локальном демо «доставлено» — ложь) → «создано и показано»; пожелание «женский/мужской» сохраняется, но система заявляет, что не угадывает характер голоса по имени (Web Speech API поля нет); «Честные границы» — отдельная секция | тест: границы объявлены в модуле; статусы проверены в браузере | UNKNOWN назван в лицо, не замаскирован |
| Интеграция без переписывания ядра | `СИНГУЛЯР_21_ОБЩЕНИЕ.html` — автономный модуль в ряду ·19/·20; карточка + Шаг 9 в навигаторе; precache sw15 v6; README/ИНСТРУКЦИЯ 4-е; релиз v1.11 | Pages после пуша; локальные тесты зелёные | ядро ·15/·16/·18 не тронуто (0 правок) |

UNKNOWN (честно): реальный ввод (ASR/ААК) не подключён — каналы ввода задекларированы моделью; Брайль —
Unicode-показ шрифтом, не драйвер дисплея; вибрация — компетенция ·19 (объявление канала); доставка —
зона ·17/·18/·19 (цикл «создано → показано»); мост ·19⇄·21 (общая личность, реальные каналы адаптации) —
следующий ход; нативные платформы (Android/Apple/Windows SAPI) дают больше параметров голоса, чем веб.

### Этап 16 — СВЯЗЬ ·22: синтез прототипа «·20 СВЯЗЬ», связывание ·18+·19+·21, пересборка ОС до 20 модулей — v1.12

Вход: прототип чужой среды «·20 СВЯЗЬ» (HTML 12 КБ + ARCHITECTURE_20_SVYAZ.md) и директива
«СИНТЕЗИРУЙ ИНТЕГРИРУЙ СВЯЗЫВАЙ И ДОДЕЛЫВАЙ НЕ ДОДЕЛАННОЕ». Его же идея следующего шага принята как ТЗ:
«CONVERSATION + CHANNEL + CAPABILITY + FALLBACK + SHARED_ACTIVITY поверх существующих транспортов ·18/·19».

| CLAIM | CODE | TEST | RESULT |
|---|---|---|---|
| Один смысл — девять каналов; выбирает человек | реестр CHANNELS (текст, файл, субтитры, голосовое, озвучка, аудио-/видеозвонок, экран, совместное пение) — единственное место с человеческими именами; нумерация прототипа «·20» конфликтовала с ·20 ФОНЕТИКА → модуль собран заново как **·22 СВЯЗЬ** | логика 49/49: 9 каналов, имена уникальны, требования честны | конфликт нумерации устранён, ярлыков нет |
| Недоступность ≠ исключение | FALLBACK-граф: каждый путь ведёт к базовому «Тексту» (работает без устройств); недоступная кнопка затемнена с причиной, не спрятана | перебор всех 128 комбинаций возможностей × 9 каналов: 0 тупиковых маршрутов | ни один мир устройств не выбрасывает человека из связи |
| Выбор человека ≥ автоматика | выбор канала сохраняется в профиле (`singulyar.svyaz.v1`), переживает перезагрузку; если выбор стал недоступен — честная причина, без молчаливой подмены | браузер: override сохранён в localStorage и после reload; логика: недоступный override возвращает отказ с причиной | человек распоряжается, система объясняет |
| Связывание ·18 + ·19 + ·21 (без переписывания ядра) | мосты: ·18 — ссылка на зал `?зал=КОД` и канал «Совместное пение» (попап зала); ·19 — имя из личности (read-only; случайно созданную при чтении базу мост удаляет, чтобы не сломать ·19), адаптация `singulyar.adaptation.v1` уважается, «любое да выигрывает» (меньше движения/крупные цели); ·21 — точная персонализация голоса остаётся там, субтитры/озвучка ·22 — каналы связи | браузер 36/36: имя «Рувсон» взято из IDB ·19, решения ·19 показаны и применены, попап зала ·18 открылся с кодом, ссылка содержит `?зал=КОД` | три модуля связаны живыми мостами, 0 правок ядра |
| Транспорт честно подписан | BroadcastChannel `singular-svyaz-v1-КОД` связывает окна одного браузера; Blob (голос/файл) переживает structured clone; между устройствами медиа ведёт зал ·18 (WebRTC mesh); SpeechRecognition не выдаётся за локальный | браузер: текст, голосовое (fake-микрофон) и файл дошли между окнами; у получателя — blob-аудио и ссылка «скачать»; «речь → текст» даёт честный статус | заявлено ровно то, что работает |
| Память принадлежит человеку | IndexedDB «singular-svyaz»: журнал + блобы; экспорт JSON (текст/метаданные), звук/файлы остаются локально; удаление всего — кнопкой | тесты: записи в журнале и хранилище, экспорт/очистка без ошибок | данные не покидают устройство |
| Доделать недоделанное | пересборка **SINGULYAR_OS_v18_20_MODULES.html**: 20 модулей (17 + ·20/·21/·22; закрыта лакуна JSON-LD — у ·15 не было записи hasPart); index v1.12: исправлен осевший счётчик «13 модулей» → 19, карточка ·22, Шаг 10; sw15 кэш v7 + precache; README Release v1.12; ИНСТРУКЦИЯ 4-ж; АРХИТЕКТУРА_22_СВЯЗЬ.md | b64 каждого модуля сверяется байт-в-байт скриптом сборки; сборка падает на любом расхождении | дорожная карта «пересборка ОС» закрыта (честный счёт: 17+3 = 20, а не «18» из дорожной карты) |
| Регрессия не сломана | ядро ·15/·16/·17/·18/·19/·20/·21 не тронуто (0 правок) | ·16 5/5 · 17 Fusion OK · 18 55/55+29/29 · 19 12/0 · 20 51/51+28/28 · 21 54/54+32/32 | всё зелёное |

UNKNOWN (честно): межустройственная связь внутри ·22 не делалась — медиа-транспорт ведёт зал ·18 (mesh ~4–5
участников, TURN нет); звонок/видео/экран в ·22 — включение, предпросмотр и выбор источника, доставка между
устройствами — зона ·18; «речь → текст» зависит от реализации браузера и не доказано офлайн; озвучка зависит
от голосов устройства; Nostr-релеи и QR-сигналинг ·17/·18 не тронуты — СВЯЗЬ поверх, не вместо.

## 2. Инвентарь поставки (только рабочее, без шума)

| Путь | Размер | Что это |
|---|---|---|
| `index.html` | — | Лендинг: отчёт + инструкция + запуск всего |
| `СИНГУЛЯР_ОС_v17_13_МОДУЛЕЙ.html` | 40.0 МБ | Главная оболочка, 13 модулей |
| `СИНГУЛЯР_15_ОРКЕСТРАТОР.html` | 0.7 МБ | Модуль ·15 v1.1 (автономный) |
| `СИНГУЛЯР_01_Когда_теряем_157_голосов.html` | 15 МБ | Платформа флагмана |
| `СИНГУЛЯР_02_ФАБРИКА_эмерджентная_архитектура.html` | 7.7 МБ | Фабрика |
| `sw15.js` + `manifest.webmanifest` + `icons/` | — | PWA-слой |
| `ДАННЫЕ/` | ~3.5 МБ | Каталог xlsx, тексты 61, корпус LRC, 157 переводов флагмана, SRT/транскрипт/превью |
| `ИНСТРУМЕНТЫ/` | ~1 МБ | Grabber (userscript), УСТАНОВЩИК Windows, КАРАОКЕ-ЛАБ |
| `ДОКУМЕНТЫ/` | — | Этот отчёт, ИНСТРУКЦИЯ_СТАРТ, ОТЧЁТ_СВЯЗЬ, ревизия ·15, мастер-план, стратегия |
| `СКРИНШОТЫ/` | 9.4 МБ | 3 папки доказательств (Платформа/Фабрика/Оркестратор) |
| Релиз v1.7 | 40 МБ | Ассет ОС: `releases/download/v1.7/СИНГУЛЯР_ОС_v17_13_МОДУЛЕЙ.html` |
| Архив поставки | ~85 МБ | `RUVSON_СИНГУЛЯР_ХОСТИНГ_ПОЛНЫЙ_v18.zip` (зеркало filebin) |

**Исключено как шум:** устаревшие архивы поколений (v21/v22/v23/v24, ОС v14/v15/v16, ОРКЕСТРАТОР v16, дубль платформы с латинским именем), архив сессии, дубли каталога, пустые README, дубли «(1)» в КАРАОКЕ, отдельный проект C65 (не входит во вселенную СИНГУЛЯР).

## 3. Качество и доказательства

- Тесты Playwright: `test_s15.py` **53/53** (boot, счётчики, реестр 62×13, валидатор, импорт-мусор отклоняется, хор поёт, часы идут, слово-подсветка, RTL на арабском, аудит 62, экспорт LRC/VTT, темп/тональность/крупный текст/PWA-честность, ноль innerHTML, консоль чиста) · `test_os.py` **44/44** (13 карточек, хоткей O, хор в iframe, мобайл, консоль чиста).
- Ассерты сборки: запрещённые сетевые паттерны, обязательные блоки, ноль innerHTML.
- Данные: 62 строки реестра · 24 759 пар · 158 языков · 4 068 ru-строк · пак 638 588 Б (gzip+b64).
- Архив поставки: MD5 roundtrip через filebin совпал (`c66e483f…`).
- Скриншоты: пульс, реестр, таймлайн, хор ru, хор ar (RTL), аудит, родословная, интеграция v1.1.

## 4. Честный остаток (не сделано — сознательно)

1. **Стемы** (Demucs/Open-Unmix WASM) — заменят репетицию там, где нет минусовки.
2. **Forced alignment** (WhisperX-класс) — пословные тайминги пока интерполяция (помечена `interp`).
3. **AudioWorklet-питч** для файловых источников.
4. **Скоринг пения** — включится только с появлением эталонной мелодии (после стемов).
5. **LRCv2, Background Fetch, MSE, virtualized list, switch access** — горизонт v1.2+.
6. **Конвейер переводов**: 228/793 LLM-дорожек, демон продолжает восточные языки.

## 5. Дорожная карта

1. Демон переводов до полного 61×13 (приоритет: восточные) → пересборка пака → перезалив.
2. Стемы в браузере → честная замена «репетиции».
3. Forced alignment по мастер-аудио для ru-дорожек.
4. Минусовки: конвейер загрузки `minus/` + IndexedDB-шаринг.
5. ОС v1.8: аудиторский конвейер по расписанию (PING → AUDIT → отчёт).
6. WebGL/WebGPU аудио-реактивный визуализатор (лакуна №4 ТЗ) и гармонизация/бэк-вокал (лакуна №5).
7. Тоны пиньиня для ·20 (компактная таблица хань→pinyin с диакритикой) и WASM-нейро-TTS.
8. SFU для залов >5 участников + TURN за симметричным NAT; пересборка ОС с ·20 (18 модулей).

## 6. Ссылки

- Сайт (PWA): https://rtynbirf.github.io/singulyar/ (после включения Pages)
- Репозиторий: https://github.com/rtynbirf/singulyar
- Релиз v1.7 (ОС 40 МБ): https://github.com/rtynbirf/singulyar/releases/tag/v1.7
- Релиз v1.9 (ОС v1.8 42 МБ, ·19 ЧЕЛОВЕК, сервер): https://github.com/rtynbirf/singulyar/releases/tag/v1.9
- Релиз v1.10 (·20 ФОНЕТИКА): https://github.com/rtynbirf/singulyar/releases/tag/v1.10
- Релиз v1.11 (·21 ОБЩЕНИЕ, чистая редакция 0.2.1): https://github.com/rtynbirf/singulyar/releases/tag/v1.11
- Релиз v1.12 (·22 СВЯЗЬ, ОС 20 модулей): https://github.com/rtynbirf/singulyar/releases/tag/v1.12
- Зеркало архива: filebin.net/ruvson-orkestrator
