Reproduserbarhet og proveniens
Kshana er bygget for å være reproduserbar: de samme inndataene gir de samme resultatene, og byggeartefaktene kan spores tilbake til kilden som produserte dem. Dette dokumentet sier nøyaktig hva som er garantert, hva som ikke er det, og hvordan garantiene håndheves.
Deterministiske garantier#
Motoren har ingen veggklokke, ingen avhengighet av utførelsestråd og ingen tilfeldighet uten seed. Hver stokastiske prosess drives av en ChaCha8Rng-strøm nøklet med scenarioets seed, trukket i fast rekkefølge. Konsekvenser:
| Egenskap | Garantert | Håndheves av |
|---|---|---|
Samme scenario, samme maskin → byte-identisk result.json |
Ja | scripts/check-reproducible.sh (kjører referansescenarioet to ganger, sammenligner SHA-256 (SHA: Secure Hash Algorithm)) |
| Samme scenario → identiske kvalitetsmål felt for felt | Ja, per plattform | tests/golden.rs fastsetter hvert kvalitetsmål (FoM) for de fire referansescenarioene |
Scenarioets inndatahash (scenario_hash) er plattformuavhengig |
Ja | innholdsadressert SHA-256 av det kanoniske scenarioet, fastsatt i tests/golden.rs |
| Inndatafingeravtrykk + utdataenes form identiske på tvers av OS (operativsystem) | Ja | tests/cross_platform_golden.rs fastsetter en nøyaktig SHA-256 per scenario (ti scenarioer, én .sha256-fil hver i tests/golden/), kontrollert på CI-matrisen (kontinuerlig integrasjon) med 3 OS |
| Utdataenes verdier stemmer overens på tvers av OS (ubuntu/macOS/Windows) | Ja, til 1e-6 | CI-jobben reproducibility-matrix kjører golden.rs (1e-6), sgp4_verification.rs (2e-5 km) og determinism.rs på alle tre OS |
| En navigasjonsmeldingsramme for lav jordbane (LEO) er de samme bytene på hver plattform og i hver byggeprofil, WebAssembly-bygget (WASM) medregnet | Ja | src/portable_math.rs (hver transcendente funksjon og hver normalavvik for typen leo-navmsg går gjennom craten libm i ren Rust); leo_navmsg::tests::the_encoded_frame_is_the_same_bytes_on_every_platform fastsetter en hel ramme uten plattformsperre |
| Trekninger av indekser med seed (bootstrap-resampling, stokkinger) er de samme på 32-bits og 64-bits mål | Ja | portable_math::uniform_index trekker alltid som u64; fastsatt i portable_math::tests |
| Samme verktøykjede overalt | Ja | rust-toolchain.toml fastsetter kanalen; scripts/check-toolchain.sh lar bygget feile ved avvik; CI og utgivelse fastsetter den samme versjonen |
| Samme avhengighetssett | Ja | Cargo.lock er innsjekket, og cargo metadata --locked brukes for SBOM-en (software bill of materials) |
Hver kommandolinjekjøring skriver også et reproduserbarhetsregister inn i rapporten sin (<scenario>.report.json og .report.html): motorversjonen, SHA-256 for scenariofilen og for resultatdokumentet, seeden, plattformen og den nøyaktige kommandoen, som tests/advanced_report_cli.rs kjører på nytt til et byte-identisk resultat. Rapporten er selv en ren funksjon av kjøringen: to kjøringer av scenarios/clock-holdover.toml skriver den samme report.json byte for byte. Se REPORTS.md.
Forbeholdet om kryssplattform (og hvordan golden-testene håndterer det)#
De numeriske resultatene er bit-identiske på en gitt plattform, men kan avvike i de siste få enhetene i siste posisjon (ULP) mellom plattformer. Årsaken er plattformens matematikkbibliotek: sqrt, ln, exp og lignende er ikke påkrevd av IEEE-754 (IEEE: Institute of Electrical and Electronics Engineers) å være korrekt avrundet, så Linux (glibc, GNU C-biblioteket), macOS og Windows kan hver returnere en forskjellig siste bit. Over en lang kjøring akkumuleres disse ~1e-16-forskjellene til kanskje ~1e-12 relativt.
To ting gjør at forskjellen i siste posisjon blir større enn den starter som, og begge er målt, ikke antatt. En adaptiv integrator velger sitt neste steg ut fra feilestimatet gjennom en femterot, så én enhet i siste posisjon endrer stegfølgen, og de to plattformene stemmer da overens bare til integrasjonstoleransen. En iterativ estimator (en minstekvadraters tilpasning, et banebestemmelsesfilter) kan ta en annen vei til konvergens. Typer bygget på noen av dem kan avvike mellom plattformer med mer enn 1e-6 i enkeltfelt; src/test_support.rs registrerer det samme regimet for enhetstestene.
Byggeprofilen betyr det samme på samme måte, på én maskin. Et optimalisert bygg på macOS slår sammen en sinus og en cosinus av ett argument til ett enkelt kall til systemets kombinerte rutine, hvis sinus avviker fra den alenestående sin i siste bit for 379 av 200 000 argumenter; et uoptimalisert bygg gjør de to kallene. Målt på aarch64 macOS over de 138 scenariofilene gir et debug- og et release-bygg av én kilde byte-identiske resultatdokumenter for 102. De øvrige 36 avviker i de siste sifrene: 28 innenfor 1e-6, ett (leo-ppp-convergence) med 2.8e-6, og sju kampanjer bare i sjekksummene for medlemskjøringene sine; ingen avviker i en etikett, et antall eller en konklusjon. Garantien om byte-identitet ovenfor gjelder derfor for ett bygg: den samme binærfilen to ganger.
De normalfordelte trekningene med seed er en tredje, mye sjeldnere kilde: sampleren kaller vertens eksponential og logaritme i sine sjeldne grener, og omtrent én trekning av en million avviker i siste bit mellom det native og WASM-bygget.
Der et utdata er diskret, er en forskjell i siste posisjon ikke akseptabel i det hele tatt, og typen beregnes med src/portable_math.rs i stedet for vertens bibliotek. Typen leo-navmsg er den første: den binære rammen er overførte heltall, og det samme scenarioet ble en gang kodet til tre forskjellige rammer: i et release-bygg, i et debug-bygg av samme kilde og i nettleseren. Nå er det de samme bytene i alle tre.
På grunn av dette fastsetter golden-testene ikke én enkelt kryssplattform-hash av flyttallsutdataene — det ville vært skjørt og ville latt ærlig korrekte bygg feile på et annet OS. I stedet:
tests/golden.rsfastsetter hvert kvalitetsmål med en relativ toleranse på1e-6— fire størrelsesordener strengere enn enhver virkelig regresjon (som flytter en verdi med hele prosent), men langt løsere enn jitter i matematikkbiblioteket (libm) på tvers av plattformer. Nettbegrensede felt (holdover-sekunder) og felt som er nøyaktig null, fastsettes nøyaktig.scenario_hash— en innholdshash av inndataene — er plattformuavhengig og fastsatt nøyaktig.tests/cross_platform_golden.rsfastsetter en nøyaktig SHA-256, innsjekket per scenario itests/golden/, over projeksjonen som er identisk på tvers av plattformer: inndatafingeravtrykket pluss utdataenes form (feltnavn, nøsting, bladtyper, arraylengder — fastsatt av deterministisk nettaritmetikk, aldri flyttallsverdiene). Dette fanger strukturelle regresjoner nøyaktig, mens toleransefastsettelsene ovenfor fanger verdiregresjoner.scripts/check-reproducible.shhåndhever byte-identiske utdata over to kjøringer på samme maskin (determinismegarantien).- CI-jobben
reproducibility-matrixkjører de fire testene ovenfor (cross_platform_golden,golden,determinism,sgp4_verification) på ubuntu-latest, macos-latest og windows-latest, så kryssplattform-reproduserbarhet hevdes ved hver push — form- og inndata-goldens nøyaktig, tallene til 1e-6, og SGP4-tilstandene (Simplified General Perturbations 4) til 2e-5 km — i stedet for å stole på ett enkelt OS.
Hvis du må lage de fastsatte tallene på nytt (for eksempel etter en tilsiktet modellendring), kjør hvert referansescenario og kopier de utskrevne FoM-verdiene inn i tests/golden.rs, og før deretter endringen inn i CHANGELOG.md.
Programvarestykkliste (SBOM)#
scripts/gen-sbom.sh lager en CycloneDX 1,5 SBOM som lister hver crate som følger med i en kshana-artefakt, med eksakt versjon, kilde og lisens. Den er en avhengighetsfri generator bygget på cargo metadata --locked (så den fungerer med bare verktøykjeden), og den går gjennom løsningsgrafen fra kshana-pakken, bare gjennom vanlige avhengigheter og byggeavhengigheter. Utviklingsavhengigheter (crater bare for test, som sgp4) er utelatt fordi ingen artefakt inneholder dem.
Grafen er unionen av funksjonssettene de utleverte artefaktene bygges med: standardbygget (biblioteket og CLI (kommandolinjegrensesnittet)), --features python (PyPI-hjulet (Python Package Index), der pyo3-kjeden er dets grense mot fremmed kode) og --features wasm (npm-pakken, som har denne samme SBOM-en inne i tarballen sin). Plattformbetingede avhengigheter for hvert mål er med, siden hjulene leveres for flere operativsystemer og npm-pakken retter seg mot WebAssembly. Ett dokument dekker alle tre artefaktene, så for en enkelt av dem er det en overmengde. Den lister for tiden 107 komponenter; antallet er fastsatt i tests/fixtures/reproducibility_software_assurance/. Den frittstående serveren kshana-mcp har sitt eget manifest og er ikke beskrevet av denne SBOM-en.
Utdataene er deterministiske — det samme avhengighetssettet gir et byte-identisk dokument, inkludert et serienummer utledet av den sorterte pakkelisten i stedet for et tidsstempel.
Utgivelsesarbeidsflyten lager SBOM-en (kshana-sbom.cdx.json) og legger den ved hver merkede utgivelse; publiseringsarbeidsflyten leverer den også ved siden av PyPI-hjulene og inne i npm-pakken.
Byggeopphav#
Utgivelsesarbeidsflyten lager en SLSA-attestering (Supply-chain Levels for Software Artifacts) av byggeopphavet (actions/attest-build-provenance) som dekker hver fil den legger ved GitHub-utgivelsen: kommandolinjebinærfilene for hver plattform, serverbinærfilen kshana-mcp, SBOM-en, valideringssammendraget og SHA256SUMS. En bruker kan med gh attestation verify verifisere at artefaktene ble bygget av dette depotets utgivelsesarbeidsflyt fra denne kilden — noe som tetter gapet mellom «her er en binærfil» og «her er en binærfil jeg kan spore til kilden». For eksempel for SBOM-en til v0.28.0:
curl -sLO https://github.com/AshfordeOU/kshana/releases/download/v0.28.0/kshana-sbom.cdx.json
gh attestation verify kshana-sbom.cdx.json --repo AshfordeOU/kshana