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

ProjetoEditar no GitHubFonte: CONTRIBUTING.md

Contribuir para o Kshana

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

A forma como o projeto é governado — quem decide, o limiar técnico e a fronteira entre o aberto e o fechado — está documentada em GOVERNANCE.md.

Desenvolvimento#

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

As ligações opcionais a linguagens estão protegidas por funcionalidades (feature-gated) e desativadas por predefinição (pelo que a compilação acima e a verificação de auditoria de dependências nunca lhes 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#

Demoram segundos. São um subconjunto da tarefa check de ci.yml, pela mesma ordem, pelo 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 determinista é um erro. A aleatoriedade tem de passar pelo gerador aleatório com semente; as execuções quânticas e clássicas usam sementes independentes, derivadas de forma determinista.
  • Higiene do repositório. Os commits e o conteúdo não podem conter nenhuma linha final nem rodapé de atribuição de ferramentas automáticas, nem nomear um assistente de IA como autor em parte alguma do conteúdo, dos nomes de ficheiros ou do histórico. A proteção aplica-o.

Antes de fazer push — a verificação completa#

scripts/gate.sh é a verificação canónica: executa cargo test --all na íntegra e depois scripts/check-repeatability.sh para voltar a executar a suite da biblioteca mais algumas vezes, porque uma condição de corrida por entrelaçamento de threads é invisível numa única execução. Só em caso de sucesso escreve .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?

É lenta de propósito — 62-79 minutos em regime estável saudável, segundo o cabeçalho de scripts/gate.sh, que contém o valor atual — e não tem tempo limite, porque um tempo limite suficientemente curto para ser útil interromperia uma execução saudável. Uma execução parcial que terminou em verde não é uma verificação completa: ambos os defeitos para os quais este mecanismo existe passaram por ela dessa forma.

Os contribuidores que trabalham a partir de um fork não precisam do hook de recibo — é uma verificação local de quem mantém o projeto, e é a CI que, na prática, controla um pull request. Executar gate.sh antes de abrir um significa apenas que a CI não lhe diz nada que ainda não soubesse.

Adicionar ou alterar um modelo de sensor#

  1. Todos os parâmetros numéricos precisam de proveniência. Coloque a citação na cadeia provenance do modelo e no ficheiro do cenário. Sem constantes anónimas.
  2. Valide face à relação normalizada, e não apenas à consistência interna — por exemplo, o desvio de Allan para relógios, o crescimento do erro de navegação por estima de Groves para sistemas inerciais, a conversão de temporização em 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 indicada.
  3. Seja honesto quanto à maturidade. O registo de estado é src/verification.rs::verification_matrix() — acrescente ou altere aí a linha, indique a sua referência independente externa (ou diga com clareza que não existe nenhuma, o que a torna Modelled) e depois regenere os artefactos 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 "do not edit by hand" por uma razão. Atualize também a narrativa de docs/VALIDATION.md quando o texto o exigir, e rotule como tal os valores que sejam objetivos ou resultados de demonstradores em solo.

Testes#

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

Commits e versionamento#

  • Conventional Commits (feat:, fix:, docs:, test:, chore: …).
  • Semantic Versioning. Antes da 1.0, o esquema de cenários/resultados pode mudar; assinale as alterações que quebram a compatibilidade.
  • As versões são lançadas por uma etiqueta vX.Y.Z e a publicação é automática, mas ordenada. O fluxo de trabalho Auto-tag envia a etiqueta quando a CI está verde em main numa subida de versão. O fluxo de trabalho Release executa a verificação completa no commit etiquetado e só quando esta é bem-sucedida publica no crates.io, no Python Package Index (PyPI), no npm, no ghcr.io, no registo 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 etiqueta. Ninguém executa cargo publish à mão. Os passos, e como repetir uma publicação falhada, estão em docs/RELEASING.md.

Manutenção do registo de alterações (obrigatória)#

Toda a alteração visível para o utilizador atualiza CHANGELOG.md:

  1. Acrescente uma entrada na secção [Unreleased], no grupo certo (Added / Changed / Fixed / Removed / Documented / Planned).
  2. Ao lançar uma versão, renomeie [Unreleased] para o novo [x.y.z] - YYYY-MM-DD, inicie um novo [Unreleased], suba o version em Cargo.toml (para que engine_version no JSON de resultados coincida), atualize as ligações de comparação no fundo e etiquete vx.y.z.
  3. Mantenha as entradas concisas e orientadas para o utilizador; ligue issues/PRs quando for útil.

Um pull request que altere o comportamento sem uma entrada no registo de alterações está incompleto.

Controlo de exportações#

A resiliência PNT e a deteção quântica podem estar sujeitas a controlos de exportação de dupla utilização. Mantenha o repositório público restrito a modelos e métodos genéricos e publicados. Tudo o que se assemelhe a profundidade de resiliência/antiengano sensível do ponto de vista da exportação pertence à camada privada, não aqui. Em caso de dúvida, pergunte antes de contribuir com isso.

Licença#

O Kshana tem licenciamento duplo (AGPL-3.0 ou uma licença comercial da Ashforde OÜ — ver LICENSING.md). Para que isso continue a funcionar, as contribuições têm de ser utilizáveis ao abrigo de ambas as licenças. Assim, ao contribuir, concorda que:

  1. a sua contribuição é licenciada à entrada ao abrigo da AGPL-3.0-only; e
  2. concede também à 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 com licenciamento comercial (ou seja, para a distribuir também ao abrigo de condições comerciais não AGPL). Mantém os direitos de autor sobre a sua contribuição.

Esta concessão leve de licença dupla — não uma cessão de direitos de autor — é o que permite ao projeto manter-se aberto e oferecer uma edição comercial. Se não puder conceder (2) (por exemplo, código pertencente a uma entidade empregadora), diga-o no seu pull request antes de contribuir.

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

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