Контекст для ИИ-агента

Точка входа для агента, работающего с этим репозиторием. Читать первым, до любых правок. Остальные страницы — по ссылкам, содержимое здесь не дублируется.

Правила работы

Корень работы — каталог этого репозитория. Не читать и не изменять ничего за его пределами: родительские каталоги, домашний каталог, системные пути. Исключение — временные файлы в каталоге scratchpad. Пути в коде, командах и документации — относительно корня репозитория.

Документация правится вместе с кодом. Изменили поведение — правьте соответствующую страницу docs/ в том же наборе коммитов. Соответствие «что сделали → что править» — в 6. Обновить документацию.

Коммиты делает только человек. Агент правит рабочее дерево и предлагает текст сообщений, но не вызывает git commit, git push, git rebase и прочие команды, меняющие историю. Готовые изменения агент оставляет незакоммиченными и показывает предлагаемое разбиение на коммиты.

Каждый коммит подписан. git commit -s, заголовок в повелительном наклонении не длиннее 50 символов. Без трейлера Signed-off-by: CI блокирует слияние. См. Как вносить изменения.

Что это за проект

Форк satnogs-flowgraphs (ветка soniks) — флоуграфы GNU Radio для наземных станций сети Соникс плюс Python-запускатор. soniks-client-new вызывает один бинарник flowgraph_dispatcher --mode <MODE>, тот выбирает флоуграф, поднимает его и три ZMQ-подписчика, пишущих кадры, аудио и IQ.

Фork добавил декодеры Geoscan и USP (Спутникс). Полная картина — Обзор, сквозной путь данных — Архитектура.

Карта репозитория

Путь

Что

Когда трогать

generic/*.grc

11 флоуграфов общего назначения

новая модуляция или общий протокол

satellites/*.grc

9 декодеров под спутники, включая Geoscan и USP

новый спутник

test_flowgraphs/*.grc

генераторы сигнала, вне сборки

отладка без эфира

tools/sync_frontend.py

раскладка общего фронтенда из generic/fm.grc по остальным графам

любая правка приёмного тракта

tests/*.py

инварианты .grc и контракт аргументов диспетчера

вместе с любой правкой кода

flowgraph_dispatcher/flowgraph_dispatcher.py

таблицы режимов, разбор аргументов, управление процессами

новый режим или аргумент

flowgraph_dispatcher/zmq_*_sub.py

запись кадров, IQ, аудио

формат выходных файлов

flowgraph_dispatcher/zmq_subs/helper_functions/

общие разборщики, сигналы, метки времени

общая логика подписчиков

*/CMakeLists.txt

явные списки собираемых файлов

добавление или удаление .grc

debian/

метаданные пакета

изменение зависимостей

docs/

эта документация

вместе с любым изменением поведения

Чего в проекте нет: Python-упаковки (setup.py, pyproject.toml), генерации API-доков, сборки пакета в CI.

Инварианты

Нарушение любого из них ломает сборку или проходит незаметно и ломает наблюдение.

  1. .grc — источник правды. generic/*.py и satellites/*.py генерирует grcc при сборке; они в .gitignore и никогда не коммитятся. Правка сгенерированного .py исчезнет при следующей сборке.

  2. Имя параметра в .grc = имя аргумента в client_argument_parser() (дефисы против подчёркиваний — единственное расхождение). Диспетчер передаёт всё как --ключ=значение вслепую, а grcc генерирует parse_args(), поэтому лишний аргумент завершает флоуграф с кодом 2. Проверяет tests/test_dispatcher.py.

  3. Списки в CMakeLists.txt явные, не по маске. Новый .grc, не внесённый в set(flowgraphs …), молча не соберётся.

  4. Порты ZMQ выводятся из одного числа. В диспетчере это --zmq-base-port (по умолчанию 16887), во флоуграфе — параметр zmq_base_port. Кадры на base, IQ на base + 1, аудио на base + 2. Литеральных адресов tcp://127.0.0.1:1688x в .grc быть не должно — это проверяет tests/test_flowgraphs.py.

  5. Новый режим = две записи в SATNOGS_FLOWGRAPH_SCRIPTS и SATNOGS_FLOWGRAPH_MODES, плюс строка в CMake. Одной недостаточно.

  6. Подписчики стартуют раньше флоуграфа. ZMQ pub/sub не буферизует для неподключённых подписчиков — порядок в run() менять нельзя.

  7. Аудио-тракт обязан выдавать ровно 48000 Гц моно. Подписчик пишет OGG с этой частотой жёстко и рассогласование не обнаруживает.

  8. decoded_data_file_path, file_path, iq_file_path, enable_iq_dump во флоуграфах ни к чему не подключены — запись файлов живёт в подписчиках. Не «чинить» их внутри .grc. doppler_correction_per_sec снят 2026-09-12, диспетчер его обнуляет.

  9. Децимация не меньше 4. Дальше по тракту есть decimation // 2 и decimation // sps; без нижней границы получается ноль.

  10. Приёмный тракт до демодулятора — один на все графы, источник правды generic/fm.grc. Править фронтенд (soapy_source, доплер-компенсация, водопад, IQ ZMQ, UDP) в другом файле бессмысленно: tools/sync_frontend.py перепишет его по золотому, а test_frontend_matches_golden не пропустит расхождение. У каждого графа свои только out_samp_rate/samp_rate водопада и compensate у iq_receiver. dev_args с 2026-09-12 живой: --dev-args доезжает до soapy_source.

Частые задачи

Задача

Куда

Добавить декодер или режим

Добавление флоуграфа и режима

Понять, что делает режим

Справочник режимов, затем Справочник флоуграфов

Разобраться в конкретном .grc

Соглашения в .grc + страница семейства

Изменить формат выходных данных

Выходные данные, правки в zmq_*_sub.py

Диагностировать отсутствие кадров

Диагностика неисправностей

Понять «почему так странно сделано»

Известные расхождения

Решить, брать ли правку из апстрима

Отношения с апстримом

Ловушки

Проверенные расхождения между тем, как код выглядит, и тем, как он работает, собраны в Известные расхождения. Самые дорогие по времени:

  • иерархические блоки — мёртвый код, правка не меняет поведение декодеров;

  • у PHASMA нет аудиоветки — OGG будет пустым, подписчик предупреждает;

  • частота дискретизации IQ нигде не записана — без параметров наблюдения файл бесполезен;

  • аудио жёстко пишется на 48000 Гц — тракт обязан выдавать ровно эту частоту.

Проверка изменений

Минимум перед коммитом:

python3 tests/test_flowgraphs.py      # инварианты .grc, без GNU Radio
python3 tests/test_dispatcher.py      # контракт аргументов, без GNU Radio
flake8 flowgraph_dispatcher tests
python3 tests/e2e_check.py            # дерево процессов, без SDR; не в CI
cd build && cmake .. && make          # все .grc проходят grcc
grcc satellites/my_decoder.grc -o /tmp && python3 /tmp/satnogs_my_decoder.py --help
make -C docs html                     # документация собирается с -W

Первые три команды не требуют GNU Radio. В CI идут они плюс сборка через grcc (джоба flowgraphs, образ станции) и документация; e2e_check.py — нет.

Прогон целиком без эфира — раздел «Собрать и проверить» в Добавление флоуграфа и режима.