Traduction automatique, non relue par un locuteur natif. L'anglais fait foi.

ProjetModifier sur GitHubSource : CONTRIBUTING.md

Contribuer à Kshana

Merci de votre intérêt. Kshana vise à être une référence neutre, reproductible et honnêtement validée pour le PNT hybride quantique/classique. Les contributions sont soumises à cette exigence : l'exactitude, les citations et la reproductibilité passent avant l'étendue.

La manière dont le projet est gouverné (qui décide, l'exigence technique, et la frontière entre ouvert et fermé) est documentée dans GOVERNANCE.md.

Développement#

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

Les liaisons de langage facultatives sont conditionnées par des fonctionnalités et désactivées par défaut (de sorte que la construction ci-dessus et la porte d'audit des dépendances ne les touchent jamais). Pour travailler dessus :

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

Avant chaque commit : la boucle rapide#

Elles prennent quelques secondes. Elles forment un sous-ensemble du job check de ci.yml, dans le même ordre, de sorte qu'un échec ici est un échec là-bas :

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
  • La reproductibilité est un invariant strict. Un changement qui rend (scenario, seed, version) non déterministe est un bogue. L'aléa doit passer par le générateur aléatoire avec graine ; les exécutions quantiques et classiques utilisent des graines indépendantes, dérivées de façon déterministe.
  • Hygiène du dépôt. Les commits et le contenu ne doivent comporter aucune mention d'attribution à un outil automatisé en fin de message ou en pied de page, et ne doivent nommer un assistant d'IA comme auteur nulle part dans le contenu, les noms de fichiers ou l'historique. Le garde-fou l'impose.

Avant de pousser : la porte complète#

scripts/gate.sh est la porte canonique : il exécute cargo test --all en intégralité, puis scripts/check-repeatability.sh pour relancer la suite de la bibliothèque quelques fois de plus, car une condition de concurrence d'entrelacement de threads est invisible lors d'une seule exécution. Ce n'est qu'en cas de succès qu'il écrit .gate-receipt.json (non suivi par git : un état machine propre à une exécution, pas du contenu).

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?

Elle est lente exprès, de 62 à 79 minutes à l'état stable sain, selon l'en-tête de scripts/gate.sh, qui porte la valeur actuelle, et il n'y a pas de délai d'expiration, parce qu'un délai assez court pour être utile interromprait une exécution saine. Une exécution partielle revenue au vert n'est pas une porte : les deux défauts pour lesquels ce mécanisme existe l'ont franchie de cette façon.

Les contributeurs qui travaillent depuis un fork n'ont pas besoin du crochet de reçu : c'est une porte locale de mainteneur, et c'est la CI qui conditionne réellement une pull request. Exécuter gate.sh avant d'en ouvrir une signifie simplement que la CI ne vous apprend rien que vous ne sachiez déjà.

Ajouter ou modifier un modèle de capteur#

  1. Chaque paramètre numérique exige une provenance. Mettez la citation dans la chaîne provenance du modèle et dans le fichier de scénario. Aucune constante anonyme.
  2. Validez par rapport à la relation standard, et pas seulement par cohérence interne : par exemple l'écart-type d'Allan pour les horloges, la croissance d'erreur d'estime de Groves pour l'inertiel, la conversion synchronisation temporelle→télémétrie pour le transfert de temps. Ajoutez un test montrant que la sortie simulée reproduit la valeur publiée/de la relation dans une tolérance indiquée.
  3. Soyez honnête sur la maturité. Le registre d'état est src/verification.rs::verification_matrix() : ajoutez ou modifiez la ligne là-bas, nommez sa référence externe indépendante (ou dites clairement qu'il n'y en a pas, ce qui la rend Modelled), puis régénérez les artefacts publiés avec cargo run --bin gen_validation_artifacts. docs/VERIFICATION-MATRIX.md, docs/MODELLED-RATIONALE.md et web/data/verification-matrix.json sont tous générés à partir de cette fonction et disent « ne pas modifier à la main » pour une raison. Mettez aussi à jour le récit de docs/VALIDATION.md lorsque le texte l'exige, et étiquetez comme tels les chiffres qui sont des cibles ou des résultats de démonstrateur au sol.

Tests#

  • Piloté par les tests : écrivez d'abord le test qui échoue, avec la valeur attendue dérivée à la main de la physique/de la relation avant d'implémenter.
  • Les tests déterministes vérifient des valeurs exactes (dérivées à la main) ; les tests statistiques vérifient une tolérance indiquée et, idéalement, moyennent sur les graines pour maîtriser la dispersion.

Commits et gestion des versions#

  • Conventional Commits (feat:, fix:, docs:, test:, chore: …).
  • Semantic Versioning. Avant la 1.0, le schéma des scénarios/résultats peut changer ; signalez les changements incompatibles.
  • Les versions sont produites par une étiquette vX.Y.Z, et la publication est automatique mais ordonnée. Le workflow Auto-tag pousse l'étiquette une fois la CI au vert sur main lors d'un changement de version. Le workflow Release exécute la vérification complète sur le commit étiqueté, et ce n'est que lorsqu'elle réussit qu'il publie sur crates.io, le Python Package Index (PyPI), npm, ghcr.io, le registre du Model Context Protocol (MCP) et la JetBrains Marketplace ; il vérifie ensuite que chaque canal sert la version et reconstruit kshana.dev à partir de l'étiquette. Personne n'exécute cargo publish à la main. Les étapes, et la façon de relancer une publication échouée, figurent dans docs/RELEASING.md.

Tenue du journal des modifications (obligatoire)#

Chaque changement visible par l'utilisateur met à jour CHANGELOG.md :

  1. Ajoutez une entrée dans la section [Unreleased], dans le bon groupe (Added / Changed / Fixed / Removed / Documented / Planned).
  2. Lors d'une version, renommez [Unreleased] en le nouveau [x.y.z] - YYYY-MM-DD, démarrez un nouveau [Unreleased], incrémentez la version dans Cargo.toml (afin que engine_version dans le JSON des résultats corresponde), mettez à jour les liens de comparaison en bas, et étiquetez vx.y.z.
  3. Gardez les entrées concises et orientées utilisateur ; liez les tickets/PR lorsque c'est utile.

Une pull request qui change le comportement sans entrée dans le journal des modifications est incomplète.

Contrôle des exportations#

La résilience PNT et la détection quantique peuvent relever des contrôles d'exportation des biens à double usage. Cantonnez le dépôt public à des modèles et méthodes génériques et publiés. Tout ce qui ressemble à une profondeur de résilience/anti-leurrage sensible à l'exportation relève de la couche privée, pas d'ici. En cas de doute, demandez avant de le contribuer.

Licence#

Kshana est sous double licence (AGPL-3.0 ou une licence commerciale d'Ashforde OÜ ; voir LICENSING.md). Pour que cela continue de fonctionner, les contributions doivent être utilisables sous les deux licences. Ainsi, en contribuant, vous acceptez que :

  1. votre contribution soit licenciée en entrée sous l'AGPL-3.0-only ; et
  2. vous accordiez aussi à Ashforde OÜ une licence perpétuelle, mondiale, libre de redevances et irrévocable d'utiliser, de modifier et de relicencier votre contribution au sein de l'édition de Kshana sous licence commerciale (c'est-à-dire de la distribuer aussi sous des conditions commerciales non AGPL). Vous conservez le droit d'auteur sur votre contribution.

Cette cession de double licence allégée, et non une cession de droit d'auteur, est ce qui permet au projet de rester ouvert et de proposer une édition commerciale. Si vous ne pouvez pas accorder (2) (par exemple pour du code appartenant à un employeur), dites-le dans votre pull request avant de contribuer.

Exception : integrations/opencpn/plugin/. Ce répertoire est sous licence GPL-3.0-or-later (voir son LICENSE) et est en dehors de la licence commerciale. Les contributions qui y sont apportées sont licenciées en entrée sous GPL-3.0-or-later seulement ; l'octroi (2) ne s'y applique pas.

Signez chaque commit pour attester le Developer Certificate of Origin : git commit -s (ajoute une ligne Signed-off-by).