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#
- Todo parâmetro numérico precisa de proveniência. Coloque a citação na cadeia
provenancedo modelo e no arquivo de cenário. Nenhuma constante anônima. - 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.
- 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 tornaModelled) e então regenere os artefatos publicados comcargo run --bin gen_validation_artifacts.docs/VERIFICATION-MATRIX.md,docs/MODELLED-RATIONALE.mdeweb/data/verification-matrix.jsonsão todos gerados a partir dessa função e dizem "não edite à mão" por um motivo. Atualize também a narrativa dedocs/VALIDATION.mdquando 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 emmainem 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 executacargo publishà mão. Os passos, e como tentar de novo uma publicação que falhou, estão emdocs/RELEASING.md.
Manutenção do changelog (obrigatória)#
Toda alteração visível ao usuário atualiza CHANGELOG.md:
- Acrescente uma entrada na seção
[Unreleased], no grupo correto (Added/Changed/Fixed/Removed/Documented/Planned). - Na versão, renomeie
[Unreleased]para o novo[x.y.z] - YYYY-MM-DD, comece um[Unreleased]novo, aumente oversionemCargo.toml(de modo queengine_versionno JSON de resultado corresponda), atualize os links de comparação no final e marque a tagvx.y.z. - 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:
- a sua contribuição é licenciada na entrada (inbound) sob a AGPL-3.0-only; e
- 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).