Tradução automática, não revista por um falante nativo. O inglês é a referência.

ProjetoEditar no GitHubFonte: CONTRIBUTING.md

Contribuir com o Kshana

Obrigado pelo seu interesse. O Kshana pretende ser uma referência neutra, reprodutível e honestamente validada para PNT híbrido quântico/clássico. As contribuições são avaliadas por esse critério: correção, citações e reprodutibilidade acima de amplitude.

Como o projeto é governado (quem decide, o critério técnico e a fronteira entre aberto e fechado) está documentado em GOVERNANCE.md.

Desenvolvimento#

cargo build
cargo test          # all tests must pass
cargo clippy        # keep it warning-clean
cargo fmt

As ligações de linguagem opcionais são protegidas por feature e desativadas por padrão (de modo que a compilação acima e o portão de auditoria de dependências nunca as tocam). Para trabalhar nelas:

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

Antes de cada commit: o ciclo rápido#

Estes levam segundos. São um subconjunto do job check de ci.yml, na mesma ordem, de modo que uma falha aqui é uma falha lá:

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
  • A reprodutibilidade é um invariante rígido. Uma alteração que torne (scenario, seed, version) não determinístico é um defeito. A aleatoriedade deve fluir pelo RNG semeado; as execuções quânticas e clássicas usam sementes independentes, derivadas de forma determinística.
  • Higiene do repositório. Commits e conteúdo não devem trazer trailers ou rodapés de atribuição de ferramentas automatizadas, e não devem nomear um assistente de IA como autor em nenhum lugar do conteúdo, dos nomes de arquivos ou do histórico. A proteção impõe isso.

Antes de enviar: o portão completo#

scripts/gate.sh é o portão canônico: executa cargo test --all sem abreviações e depois scripts/check-repeatability.sh para reexecutar mais algumas vezes a suíte da biblioteca, porque uma condição de corrida de intercalação de threads é invisível em uma única execução. Somente em caso de sucesso grava .gate-receipt.json (não rastreado: estado da máquina sobre uma execução, não conteúdo).

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?

É lento de propósito (62-79 minutos em regime estável saudável, segundo o cabeçalho de scripts/gate.sh, que traz o valor atual) e não há tempo limite, porque um tempo limite curto o bastante para ser útil mataria uma execução saudável. Uma execução parcial que voltou verde não é um portão: os dois defeitos para os quais este mecanismo existe passaram por ela dessa maneira.

Os colaboradores que trabalham a partir de um fork não precisam do hook de recibo: é um portão local de mantenedores, e a CI é o que de fato barra um pull request. Executar gate.sh antes de abrir um significa apenas que a CI não lhe dirá nada que você já não soubesse.

Adicionar ou alterar um modelo de sensor#

  1. Todo parâmetro numérico precisa de proveniência. Coloque a citação na cadeia provenance do modelo e no arquivo de cenário. Nenhuma constante anônima.
  2. Valide contra a relação padrão, e não apenas contra a consistência interna; por exemplo, o desvio de Allan para relógios, o crescimento do erro de navegação por estima de Groves para inerciais, a conversão temporização→distância para a transferência de tempo. Acrescente um teste de que a saída simulada reproduz o valor publicado/da relação dentro de uma tolerância declarada.
  3. Seja honesto quanto à maturidade. O registro de situação é src/verification.rs::verification_matrix(): acrescente ou altere a linha ali, indique a sua referência independente externa (ou diga com clareza que não há nenhuma, o que a torna Modelled) e então regenere os artefatos publicados com cargo run --bin gen_validation_artifacts. docs/VERIFICATION-MATRIX.md, docs/MODELLED-RATIONALE.md e web/data/verification-matrix.json são todos gerados a partir dessa função e dizem "não edite à mão" por um motivo. Atualize também a narrativa de docs/VALIDATION.md quando o texto exigir e rotule como tais as figuras que são metas ou resultados de demonstradores em solo.

Testes#

  • Orientado por testes: escreva primeiro o teste que falha, com o valor esperado derivado à mão da física/relação antes de implementar.
  • Os testes determinísticos verificam valores exatos (derivados à mão); os testes estatísticos verificam uma tolerância declarada e, idealmente, fazem a média entre sementes para controlar a dispersão.

Commits e versionamento#

  • Conventional Commits (feat:, fix:, docs:, test:, chore: …).
  • Versionamento Semântico. Antes da 1.0, o esquema de cenário/resultado pode mudar; destaque as alterações incompatíveis.
  • As versões são geradas por uma tag vX.Y.Z, e a publicação é automática, mas ordenada. O fluxo de trabalho Auto-tag envia a tag quando a CI está verde em main em um aumento de versão. O fluxo de trabalho Release executa a verificação completa no commit com a tag e somente quando ela passa publica no crates.io, no Python Package Index (PyPI), no npm, no ghcr.io, no registro do Model Context Protocol (MCP) e no JetBrains Marketplace; em seguida verifica se todos os canais servem a versão e reconstrói o kshana.dev a partir da tag. Ninguém executa cargo publish à mão. Os passos, e como tentar de novo uma publicação que falhou, estão em docs/RELEASING.md.

Manutenção do changelog (obrigatória)#

Toda alteração visível ao usuário atualiza CHANGELOG.md:

  1. Acrescente uma entrada na seção [Unreleased], no grupo correto (Added / Changed / Fixed / Removed / Documented / Planned).
  2. Na versão, renomeie [Unreleased] para o novo [x.y.z] - YYYY-MM-DD, comece um [Unreleased] novo, aumente o version em Cargo.toml (de modo que engine_version no JSON de resultado corresponda), atualize os links de comparação no final e marque a tag vx.y.z.
  3. Mantenha as entradas concisas e voltadas ao usuário; inclua links para issues/PRs quando útil.

Um pull request que altera o comportamento sem uma entrada no changelog está incompleto.

Controle de exportação#

A resiliência de PNT e a detecção quântica podem se sujeitar a controles de exportação de uso duplo. Mantenha o repositório público em modelos e métodos genéricos e publicados. Qualquer coisa que se assemelhe a profundidade de resiliência/antispoofing sensível à exportação pertence à camada privada, não aqui. Em caso de dúvida, pergunte antes de contribuir com isso.

Licença#

O Kshana tem licença dupla (AGPL-3.0 ou uma licença comercial da Ashforde OÜ; veja LICENSING.md). Para que isso continue funcionando, as contribuições devem ser utilizáveis sob ambas as licenças. Portanto, ao contribuir, você concorda que:

  1. a sua contribuição é licenciada na entrada (inbound) sob a AGPL-3.0-only; e
  2. você também concede à Ashforde OÜ uma licença perpétua, mundial, isenta de royalties e irrevogável para usar, modificar e relicenciar a sua contribuição como parte da edição do Kshana licenciada comercialmente (isto é, para distribuí-la também sob termos comerciais não AGPL). Você mantém os direitos autorais da sua contribuição.

Esta concessão leve de licença dupla, que não é uma cessão de direitos autorais, é o que permite que o projeto permaneça aberto e ofereça uma edição comercial. Se você não puder conceder (2) (por exemplo, código de propriedade do empregador), diga isso no seu pull request antes de contribuir.

Exceção: integrations/opencpn/plugin/. Esse diretório é licenciado sob a GPL-3.0-or-later (veja o seu LICENSE) e está fora da licença comercial. As contribuições a ele são licenciadas na entrada sob a GPL-3.0-or-later apenas; a concessão (2) não se aplica a elas.

Assine cada commit para atestar o Developer Certificate of Origin: git commit -s (acrescenta uma linha Signed-off-by).