Машинный перевод, не проверенный носителем языка. Эталоном служит английская версия.

ПроектПравить на GitHubИсточник: CONTRIBUTING.md

Участие в разработке 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 не сообщит вам ничего нового.

Добавление или изменение модели датчика#

  1. Каждому числовому параметру нужно происхождение. Поместите ссылку на источник в строку provenance модели и в файл сценария. Безымянных констант быть не должно.
  2. Проверяйте по стандартному соотношению, а не только по внутренней согласованности — например, девиация Аллана для часов, рост ошибки счисления пути по Groves для инерциальных систем, преобразование времени в дальность для передачи времени. Добавьте тест, показывающий, что смоделированный результат воспроизводит опубликованное значение или значение из соотношения в пределах указанного допуска.
  3. Будьте честны в отношении зрелости. Реестр статусов — это 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:

  1. Добавьте запись в раздел [Unreleased] в нужной группе (Added / Changed / Fixed / Removed / Documented / Planned).
  2. При выпуске релиза переименуйте [Unreleased] в новый [x.y.z] - YYYY-MM-DD, начните новый [Unreleased], повысьте version в Cargo.toml (чтобы engine_version в JSON результата совпадало), обновите ссылки сравнения внизу и поставьте тег vx.y.z.
  3. Пишите записи кратко и для пользователя; при необходимости давайте ссылки на задачи и запросы на слияние.

Запрос на слияние, изменяющий поведение без записи в журнале изменений, считается незавершённым.

Экспортный контроль#

Устойчивость PNT и квантовые датчики могут подпадать под экспортный контроль товаров двойного назначения. Ограничивайте публичный репозиторий общими опубликованными моделями и методами. Всё, что похоже на экспортно чувствительную глубину устойчивости или защиты от спуфинга, относится к закрытому дополнению, а не сюда. Если сомневаетесь, спросите до того, как вносить это.

Лицензия#

Kshana имеет двойную лицензию (AGPL-3.0 или коммерческая лицензия от Ashforde OÜ — см. LICENSING.md). Чтобы это продолжало работать, вклад должен быть пригоден для использования по обеим лицензиям. Поэтому, внося вклад, вы соглашаетесь, что:

  1. ваш вклад лицензируется на входе по AGPL-3.0-only; и
  2. вы также предоставляете 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).