Участие в разработке Kshana
Спасибо за интерес. Kshana стремится быть нейтральным, воспроизводимым и честно проверенным эталоном для гибридного квантового/классического PNT. Вклад оценивается по этому порогу: корректность, ссылки на источники и воспроизводимость важнее широты охвата.
Как управляется проект — кто принимает решения, технический порог и граница между открытым и закрытым — описано в GOVERNANCE.md.
Разработка#
cargo build
cargo test # all tests must pass
cargo clippy # keep it warning-clean
cargo fmt
Необязательные языковые привязки включаются функциями и по умолчанию выключены (поэтому приведённая выше сборка и проверка зависимостей никогда их не затрагивают). Чтобы работать над ними:
maturin develop --features python # Python extension (needs maturin)
wasm-pack build --target web -- --features wasm # WebAssembly module
cargo clippy --features python --features wasm # lint the binding modules
Перед каждым коммитом — быстрый цикл#
Эти проверки занимают секунды. Они образуют подмножество задания check из ci.yml, в том же порядке, так что сбой здесь — это сбой и там:
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
./scripts/check-reproducible.sh # reference scenario is byte-identical across runs
./scripts/check-no-attribution.sh # repo hygiene (see below)
./scripts/check-version-sync.sh # every version surface agrees with Cargo.toml
./scripts/check-doc-coverage.sh # missing-docs ratchet: the count may fall, never rise
- Воспроизводимость — жёсткий инвариант. Изменение, из-за которого
(scenario, seed, version)становится недетерминированным, считается ошибкой. Случайность должна проходить через генератор с начальным значением (seed); квантовые и классические прогоны используют независимые, детерминированно выведенные начальные значения. - Гигиена репозитория. В коммитах и содержимом не должно быть завершающих строк или подписей с указанием автоматизированных инструментов, и нигде в содержимом, именах файлов или истории не должен называться в качестве автора ИИ-ассистент. Проверка в CI следит за этим.
Перед отправкой — полная проверка#
scripts/gate.sh — основная проверка: она выполняет cargo test --all без сокращений, затем scripts/check-repeatability.sh, чтобы ещё несколько раз прогнать набор тестов библиотеки, поскольку гонка из-за чередования потоков не видна при одном прогоне. Только при успехе она записывает .gate-receipt.json (не отслеживается в git: это состояние машины об одном прогоне, а не содержимое).
scripts/gate.sh
REPEAT=0 scripts/gate.sh # canonical suite only, no repeatability loop — a LOCAL
# shortcut: the pre-push gate refuses its receipt unless
# KSHANA_MIN_REPEAT_RUNS=0 is also set on the push
TEST_THREADS=6 scripts/gate.sh # cap per-binary concurrency if the run is memory-starved
scripts/check-gate-receipt.sh # is there a valid receipt for the commit being pushed?
scripts/install-gate-hook.sh --check # is the pre-push hook installed on this clone?
Она медленная намеренно — 62–79 минут в нормальном установившемся состоянии, согласно заголовку scripts/gate.sh, где указано актуальное значение, — и тайм-аута нет, потому что достаточно короткий и при этом полезный тайм-аут прервал бы исправный прогон. Прогон подмножества, завершившийся успешно, не является проверкой: оба дефекта, ради которых создан этот механизм, прошли именно так.
Участникам, работающим из форка, хук с квитанцией не нужен: это локальная проверка сопровождающих, а запрос на слияние на деле проверяет CI. Запуск gate.sh перед его открытием просто означает, что CI не сообщит вам ничего нового.
Добавление или изменение модели датчика#
- Каждому числовому параметру нужно происхождение. Поместите ссылку на источник в строку
provenanceмодели и в файл сценария. Безымянных констант быть не должно. - Проверяйте по стандартному соотношению, а не только по внутренней согласованности — например, девиация Аллана для часов, рост ошибки счисления пути по Groves для инерциальных систем, преобразование времени в дальность для передачи времени. Добавьте тест, показывающий, что смоделированный результат воспроизводит опубликованное значение или значение из соотношения в пределах указанного допуска.
- Будьте честны в отношении зрелости. Реестр статусов — это
src/verification.rs::verification_matrix(): добавьте или измените там строку, назовите её внешний оракул (или прямо укажите, что его нет, и тогда этоModelled), затем заново сформируйте опубликованные артефакты с помощьюcargo run --bin gen_validation_artifacts.docs/VERIFICATION-MATRIX.md,docs/MODELLED-RATIONALE.mdиweb/data/verification-matrix.jsonформируются из этой функции, и пометка «не править вручную» стоит там не случайно. Обновите также повествование вdocs/VALIDATION.md, если это требуется для текста, и помечайте показатели, являющиеся целями или результатами наземного демонстратора, соответствующим образом.
Тесты#
- Разработка через тестирование: сначала напишите падающий тест, с ожидаемым значением, выведенным вручную из физики или соотношения до реализации.
- Детерминированные тесты проверяют точные (выведенные вручную) значения; статистические тесты проверяют указанный допуск и, в идеале, усредняют по начальным значениям, чтобы контролировать разброс.
Коммиты и версии#
- Conventional Commits (
feat:,fix:,docs:,test:,chore:…). - Семантическое версионирование. До версии 1.0 схема сценария и результата может меняться; обязательно указывайте несовместимые изменения.
- Релизы выпускаются тегом
vX.Y.Z, а публикация автоматическая, но упорядоченная. Рабочий процесс Auto-tag отправляет тег, когда CI зелёный наmainпосле повышения версии. Рабочий процесс Release выполняет полную проверку на помеченном коммите и только при её успехе публикует в crates.io, Python Package Index (PyPI), npm, ghcr.io, реестр Model Context Protocol (MCP) и JetBrains Marketplace; затем он проверяет, что каждый канал отдаёт эту версию, и пересобирает kshana.dev по тегу. Никто не запускаетcargo publishвручную. Шаги и способ повторить неудавшуюся публикацию описаны вdocs/RELEASING.md.
Ведение журнала изменений (обязательно)#
Каждое видимое пользователю изменение обновляет CHANGELOG.md:
- Добавьте запись в раздел
[Unreleased]в нужной группе (Added/Changed/Fixed/Removed/Documented/Planned). - При выпуске релиза переименуйте
[Unreleased]в новый[x.y.z] - YYYY-MM-DD, начните новый[Unreleased], повысьтеversionвCargo.toml(чтобыengine_versionв JSON результата совпадало), обновите ссылки сравнения внизу и поставьте тегvx.y.z. - Пишите записи кратко и для пользователя; при необходимости давайте ссылки на задачи и запросы на слияние.
Запрос на слияние, изменяющий поведение без записи в журнале изменений, считается незавершённым.
Экспортный контроль#
Устойчивость PNT и квантовые датчики могут подпадать под экспортный контроль товаров двойного назначения. Ограничивайте публичный репозиторий общими опубликованными моделями и методами. Всё, что похоже на экспортно чувствительную глубину устойчивости или защиты от спуфинга, относится к закрытому дополнению, а не сюда. Если сомневаетесь, спросите до того, как вносить это.
Лицензия#
Kshana имеет двойную лицензию (AGPL-3.0 или коммерческая лицензия от Ashforde OÜ — см. LICENSING.md). Чтобы это продолжало работать, вклад должен быть пригоден для использования по обеим лицензиям. Поэтому, внося вклад, вы соглашаетесь, что:
- ваш вклад лицензируется на входе по AGPL-3.0-only; и
- вы также предоставляете Ashforde OÜ бессрочную, всемирную, безвозмездную, безотзывную лицензию на использование, изменение и перелицензирование вашего вклада в составе коммерчески лицензируемой редакции Kshana (то есть на распространение его также на коммерческих условиях, отличных от AGPL). Авторские права на ваш вклад остаются за вами.
Это облегчённое предоставление двойной лицензии — не передача авторских прав — позволяет проекту оставаться открытым и предлагать коммерческую редакцию. Если вы не можете предоставить (2) (например, из-за кода, принадлежащего работодателю), скажите об этом в запросе на слияние до внесения вклада.
Исключение: integrations/opencpn/plugin/. Этот каталог лицензируется по GPL-3.0-or-later (см. его LICENSE) и не входит в коммерческую лицензию. Вклад в него лицензируется на входе только по GPL-3.0-or-later; предоставление (2) на него не распространяется.
Подписывайте каждый коммит, чтобы подтвердить Developer Certificate of Origin: git commit -s (добавляет строку Signed-off-by).