stegterm/NOTES.md
2026-09-14 11:00:27 +03:00

76 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Заметки по разработке stegterm
Чистое описание того, что есть — в README.md/README.ru.md (отдельного
ARCHITECTURE.md для проекта такого размера не заводил — три пакета и
один экран, README уже покрывает структуру).
Этот файл — то, что не годится в README, потому что описывает не «как
устроено», а «на что обратить внимание» и «откуда это унаследовано».
Весь код (и здесь, и в родительском burterm, откуда это выделено)
писался в среде без сети и без установленного Go — ни разу не проходил
через компилятор.
## Происхождение
Код `internal/stego` и `internal/audio` перенесён из burterm без
изменений в логике — только module path в импортах. `internal/tui`
переписан с нуля под односкреенный интерфейс (в burterm это была
одна из 14 вкладок с общей корневой моделью на все вкладки сразу;
здесь — тонкая обёртка `Model` вокруг того же `stegoModel`, без
таб-бара, без переключения между экранами).
## Реальный баг, найденный при разработке (до переноса)
**Задвоенное объявление `ifft`/`instantaneousFrequency`.** При
добавлении SSTV-декодера в дереве оказался файл `hilbert.go`,
дублирующий функции уже написанного `sstv.go` с другой сигнатурой —
гарантированная ошибка компиляции. Как он возник — не установлено;
удалён, вся логика осталась в `sstv.go`, проверено на отсутствие
повторных объявлений по всему пакету `audio`.
## Непроверенные места (по убыванию вероятности проблем)
1. **`go.mod`: версии `bubbles`/`bubbletea`/`lipgloss`** — указаны по
памяти (та же версия, что использовалась в burterm на момент
выделения этого кода), `go mod tidy` может подтянуть другие,
`go.sum` пересоберётся с нуля.
2. **bubbles API**`Focus()` у `textinput` в некоторых версиях
возвращает `tea.Cmd`, в некоторых — нет.
3. **Kitty graphics protocol** (`internal/stego/kitty.go`) —
единственное место, где неопределённость не в компиляции, а в
визуальном поведении: что произойдёт, когда bubbletea в alt-screen
режиме перерисует экран поверх уже показанной картинки, предсказать
без реального терминала нельзя. Отсюда клавиша `ctrl+v` — передать
escape-код заново.
4. **Калибровка SSTV Robot36** (`internal/audio/sstv.go`) — тайминги
строк (`robot36SyncMs`, `robot36YMs` и т.д.) взяты по опубликованным
спецификациям, без эталонной записи для сверки. Это качественно
другой риск, чем у спектрограммы: спектрограмма не требует точной
калибровки (громче = ярче, любой вход даёт осмысленный результат),
SSTV — требует, иначе на выходе шум/диагональные полосы вместо
картинки. Авто-детект VIS-заголовка не реализован — режим (пока
только Robot36) заложен в код напрямую, без выбора в UI.
5. **Бюджет высоты `View()` не проверен построчно.** В отличие от
burterm (где после нескольких провалов этот вопрос был разобран
построчно для каждой вкладки — см. историю в NOTES.md burterm),
здесь `stegoModel.SetSize` вообще не использует высоту для
раскладки (только ширину, для решения "две колонки или один
столбец") — то есть класс бага "рамка/футер выталкивают верх экрана
за пределы видимой области" сюда не переносится по конструкции. Но
само по себе это не проверено на реальном терминале, просто риск
принципиально другого рода (максимум — обрежется низ длинного
контента, а не потеряется верх экрана целиком).
## Известные ограничения — сознательный выбор, не недоделка
- **Только WAV**, не MP3/FLAC — сжатие с потерями убивает как раз ту
мелкую структуру спектра, в которую в CTF прячут сообщения.
- **Только Robot36** из всех SSTV-режимов — самый частый в CTF-задачах
и достаточно документированный, чтобы взяться за него первым. Другие
режимы (Martin, Scottie, PD) потребовали бы свой набор таймингов и
свою калибровку — тот же риск, что и с Robot36, умноженный на число
режимов.
- **Поля "второе изображение" (для XOR) и "длина LSB-извлечения"
всегда на экране**, даже в режиме аудио, где не используются —
условный layout ради их скрытия усложнил бы `View()` заметнее, чем
стоит того.