Статус и область версии
Status: Implemented. SDD-0015 снимает блокировку обучения для классов с единственным сохранённым начертанием: система автоматически создаёт воспроизводимый синтетический базовый вариант до train/validation-разделения. Сохранённые сгенерированные руны считаются обычными базовыми вариантами наравне с нарисованными пользователем.
Требования и трассировка
- R-LIB-01 Именованные символы и несколько вариантов одного штриха. →
DrawingPad, saveCurrentSample.
- R-LIB-02 Сглаживание, шаг около 10 px, координаты 0…1 и 100 пар. →
processDrawing.
- R-LIB-03 / LIB-003 В открытой «Книге заклинаний» можно призывать случайные одноштриховые руны, обновлять вариант до подходящего, назвать его и записать как новый символ с первым образцом. Форма строится только динамикой случайного ведения пера: плавная кривизна, притяжение к центру и защита от длительного повторного прохождения по уже нарисованной линии. Небольшие самопересечения разрешены. →
buildRandomRune, runeOverlapStats, createRandomRuneDraft, addRandomRune.
- R-LIB-04 / BOOK-001 Поддерживаются несколько «Книг заклинаний». Каждая книга имеет собственный набор рун и ревизию; обучение использует только открытую книгу, а модель запоминает её ID и имя. Старый единичный гримуар мигрирует в «Основную книгу».
- R-LIB-05 / GEN-SET-001 Генератор случайной руны имеет ⚙ настройки физики движения и фильтра принятия, включая настраиваемый радиус наложения между несоседними точками. Есть мягкий, сбалансированный и строгий профили.
- R-DATA-01 / ML-001 Стратифицированное разделение выполняется по базовым вариантам до массовой аугментации. Сохранённые генератором руны равноправны пользовательским, а если у класса только один базовый вариант, второй автоматически синтезируется воспроизводимой деформацией до split. →
ensureSplitSourceSamples, stratifiedSplitSources.
- R-DATA-02 / ML-004 Настраиваемое выравнивание количества примеров каждого класса. →
buildPartitionDataset.
- R-DATA-03 / ML-006 Положение сохраняется либо форма центрируется и вписывается. Одинаковая обработка применяется при обучении и тестировании. →
applyNormalizationMode.
- R-DATA-04 / ML-007 Шум рисования моделируется как непрерывная деформация жеста: плавное поперечное отклонение + медленный двумерный дрейф с повторной интерполяцией в 100 равноудалённых точек. Независимый jitter каждой координаты запрещён. После деформации путь снова интерполируется по длине, чтобы формат совпадал с реальным вводом. →
distortStrokeTrajectory, smoothRandomSeries, resampleNormalizedPath.
- R-DATA-05 / ML-008 Один сохранённый вариант не блокирует обучение: до split автоматически создаётся воспроизводимый synthetic source с отдельным ID и родительской ссылкой. Сохранённые варианты с
source=random-rune-generator не выделяются в особую категорию и участвуют как обычная база. → syntheticBootstrapSettings, createSyntheticSourceSample, ensureSplitSourceSamples.
- R-UX-10 / UX-012 Состояние кнопки «Создать ритуальный набор» вычисляется теми же правилами, что и фактическая валидация данных. Если действие недоступно, непосредственно рядом выводятся все причины; один сохранённый вариант на класс не является причиной блокировки. →
inspectTrainingData, updateTrainingControls.
- R-TRAIN-01 Настраиваемая архитектура, оптимизатор, аугментация и автоостановка. →
getTrainingSettings, createModel.
- R-TRAIN-02 / ML-002 Ручная остановка и лимит времени проверяются после каждого пакета; модель сохраняется после хотя бы одного выполненного пакета. → callbacks
onBatchEnd.
- R-PERF-01 / PERF-001 До запуска оцениваются параметры, набор, память и размер модели; чрезмерная конфигурация блокируется. →
estimateTrainingPlan.
- R-EVAL-01 / EVAL-001 После восстановления лучших весов заново вычисляются train/validation-метрики, точность по классам и матрица ошибок. →
evaluateModel.
- R-MODEL-01 / MODEL-001 Модель хранит книгу-источник, версию приложения и TensorFlow.js, ревизию и отпечаток библиотеки книги, seed, состав частей данных, предобработку и распределение классов.
- R-STORAGE-01 / STORAGE-002 Один JSON экспортирует и восстанавливает все книги заклинаний, настройки, метаданные и веса моделей. →
exportBackup, importBackupFile.
- R-TEST-01 После отпускания штриха выбранная модель выдаёт победителя и полный отсортированный рейтинг. →
classifyPoints.
- R-FEEDBACK-01 / FEEDBACK-001 Пользователь подтверждает победителя или выбирает правильный символ; исходный тестовый штрих добавляется в книгу-источник модели с происхождением обратной связи. →
addTestDrawingToSymbol.
- R-UX-02 / UX-003 На смартфонах тестирование занимает доступную высоту экрана без прокрутки документа; длинные рейтинги и список исправлений ограничены внутренними областями. →
body.is-testing-mode.
- R-UX-03 / UX-004 Портретный смартфон использует одноэкранную композицию: крупный canvas, компактный результат, функциональная строка модели вместо глобальной шапки и навигация без прокрутки страницы.
- R-UX-04 / UX-005 Исправление класса и полный рейтинг раскрываются как bottom sheet — нижняя панель поверх текущего экрана; новый штрих автоматически сбрасывает предыдущий результат.
- R-UX-05 / UX-006 Игровой слой использует единый магический визуальный язык: гримуар, руны, оракулы, ритуал обучения и магический круг; технические ML-параметры остаются доступными в режиме ритуала.
- R-UX-06 / UX-007 Визуальная иерархия не зависит от рамок: основные секции, списки, метрики, модели, bottom sheet и навигация разделяются пространством, тоном и свечением; контур сохраняется только там, где обозначает интерактивную границу или фокус.
- R-UX-07 / UX-008 Геометрия режима начертания фиксирована: размер магического круга и область результата не меняются при переходах empty → processing → result → feedback.
- R-UX-08 / UX-009 Сохранённые модели управляются на отдельном экране «Оракулы»; экран ритуала посвящён настройке и ходу обучения.
- R-UX-09 / UX-011 Экран ⚙ настроек генератора адаптируется по ширине: на смартфоне занимает весь viewport, параметры становятся строками «название → значение», действия закреплены снизу; на планшете и desktop сохраняется двухколоночная сетка без горизонтальной прокрутки.
- R-PLATFORM-01 WebGL используется для аппаратного ускорения, CPU — как выбранный или резервный движок. →
switchBackend.
- R-BOOT-01 / UX-010 Проект поставляется одним HTML. До «Войти» приложение уже присутствует в DOM, но скрыто через
display:none; TensorFlow.js не запрашивается, а основной JS хранится как инертный script type="text/plain" и не выполняется. После входа минимальный bootstrap показывает интерфейс, динамически подключает TensorFlow.js и запускает основной код.
Ключевые решения
- D-001. Для каждого непустого класса формируются минимум два базовых варианта. Если сохранён только один, система создаёт дополнительный синтетический базовый вариант до train/validation-разделения. Это позволяет обучаться сразу, но synthetic validation не считается независимой человеческой контрольной выборкой.
- D-002. Итоговая матрица ошибок строится по базовым вариантам validation до массового размножения. Они могут быть сохранёнными пользовательскими/сгенерированными либо автоматически синтезированными при bootstrap.
- D-003. Seed фиксирует состав и преобразования набора; вычисления разных видеочипов могут всё равно дать небольшие численные различия.
- D-004. Импорт сначала проверяет и временно сохраняет новые модели; текущие данные заменяются только после успешной подготовки.
- D-005. Progressive disclosure — постепенное раскрытие: на основном тестовом экране постоянно остаются только модель, движок, canvas, главный ответ, обратная связь и две ближайшие альтернативы; длинные списки открываются поверх экрана.
D-006. Borderless hierarchy — безрамочная иерархия: сначала пространство и контраст, затем фон/свечение, и только в последнюю очередь явный контур.
D-007. Коррелированное искажение строится по нескольким случайным опорным значениям вдоль штриха и интерполируется Catmull–Rom-кривой. Поэтому соседние точки движутся согласованно, а параметр плавности задаёт характерный масштаб изгиба.
D-008. Stable layout — стабильная компоновка: место под толкование резервируется до рисования, поэтому empty, processing, result и feedback меняют только содержимое, но не размеры областей.
D-009. Экран «Оракулы» является единственным местом управления сохранёнными моделями; «Ритуал» отвечает за создание модели, «Начертание» — за её использование.
D-010. Случайная руна строится как динамическая траектория пера, а не как выбор готовой формы. Направление и кривизна плавно блуждают; по мере удаления от центра усиливается возвращающая сила, а у границы — дополнительное мягкое отталкивание. Проверка истории разрешает краткие самопересечения, но отклоняет длительное ведение поверх старого участка. Итоговый путь пересчитывается в 100 равноудалённых точек.
D-011. В однофайловой сборке браузер неизбежно скачивает и парсит HTML/CSS целиком. Оптимизируется не передача байтов, а момент работы: основной DOM скрыт до входа, TensorFlow.js не создаёт сетевой запрос, а код приложения не компилируется и не выполняется. Единственный исполняемый код до входа — небольшой bootstrap обработчика кнопки.
D-012. На узком экране плотность настроек уменьшается не за счёт уменьшения шрифта, а за счёт смены композиции: подпись и числовое поле располагаются в одной строке, внутренний контент прокручивается независимо, а панель применения остаётся видимой у нижнего safe area.
D-013. Поворот является независимым геометрическим преобразованием аугментации: для каждой копии угол равномерно выбирается из симметричного диапазона ±N градусов и применяется вокруг центроида штриха до масштабирования, смещения и деформации ведения.
Критерии приёмки
- Кнопка обновления случайной руны каждый раз создаёт связный одноштриховый знак из 100 точек без шаблонов формы; траектория остаётся внутри безопасной области, может кратко пересекать себя, но не допускает длинной серии совпадающих со старым следом точек. После ввода уникального имени «Вписать в книгу» создаёт новый символ ровно с одним первым образцом и метаданными генератора.
- Ни один эффективный базовый
sampleId не встречается одновременно в train и validation, включая все его аугментированные копии. Класс с одним сохранённым вариантом автоматически получает отдельный синтетический базовый ID для недостающей части.
- При включённом балансе каждый класс имеет одинаковое количество сгенерированных примеров внутри каждой части.
- Класс с одним сохранённым вариантом проходит валидацию данных и получает минимум один train и один validation базовый вариант; интерфейс предупреждает, что такая проверка частично синтетическая, но не блокирует запуск.
- Если «Создать ритуальный набор» отключена, под кнопкой видна конкретная причина. При двух непустых классах с одним корректным вариантом у каждого кнопка активна, потому что вторые базовые варианты создаются автоматически.
- При одинаковом seed и настройках траекторная деформация воспроизводима; соседние смещения коррелированы и не образуют независимый пиксельный jitter.
- Параметр «Поворот, ±°» по умолчанию равен 30: каждая аугментированная копия получает воспроизводимый по seed угол из равномерного диапазона −30°…+30° вокруг центроида штриха; значение 0 полностью отключает вращение.
- Остановка после первого выполненного пакета завершает обучение и сохраняет пригодную к загрузке модель.
- Опасный план обучения требует подтверждения, а конфигурация выше жёсткого лимита не запускается.
- Карточка модели показывает пересчитанную validation accuracy; окно оценки содержит точность каждого класса и матрицу ошибок.
- Экспортированный JSON после импорта восстанавливает библиотеку, настройки и доступные веса моделей.
- После перезагрузки сохранённая модель загружается и выдаёт полный рейтинг классов.
- Кнопка «✓ Это …» добавляет исходный штрих в класс-победитель; «Исправить» открывает bottom sheet с рунами книги-источника оракула и добавляет штрих в выбранный класс только один раз.
- При ширине 320 px и типичной высоте смартфона документ в режиме тестирования не имеет вертикальной прокрутки; глобальная шапка скрыта, а canvas и результат полностью размещаются над нижней навигацией.
- Магический круг не меняет размер во время распознавания и после появления результата; область толкования зарезервирована заранее.
- Навигация содержит отдельный экран «Оракулы», а карточки сохранённых моделей отсутствуют на экране «Ритуал».
- На основных экранах карточки, строки списков, метрики, графики, модели, навигация и bottom sheet не используют декоративную обводку; поле начертания сохраняет различимую интерактивную границу.
- При ширине 320–390 px окно настроек генератора занимает доступный viewport без горизонтальной прокрутки, числовые поля остаются доступны для касания, а кнопки применения и сброса закреплены у нижней границы. При ширине 621–900 px двухколоночная сетка также не создаёт горизонтального переполнения.
- До нажатия «Войти»
#appShell имеет display:none, отсутствует загруженный TensorFlow.js и в DOM нет script[data-tfjs-lazy]; основной код приложения остаётся в инертном блоке. После входа shell показывается без навигации на другой документ, внешний TensorFlow.js запрашивается впервые, а основной код выполняется ровно один раз.
- При недоступности WebGL автоматический режим использует CPU.
Evidence — доказательства
Backlog после SDD-0017
- WebGPU, офлайн-кэш CDN, порог «неизвестный символ» и сравнение моделей остаются за пределами этой версии.