Maskinöversättning, inte granskad av en modersmålstalare. Engelska är referensen.

Validering och evidensRedigera på GitHubKälla: docs/REPRODUCIBILITY.md

Reproducerbarhet och proveniens

Kshana är byggt för att vara reproducerbart: samma indata ger samma resultat, och byggartefakterna kan spåras tillbaka till den källkod som producerade dem. Det här dokumentet anger exakt vad som garanteras, vad som inte garanteras och hur garantierna upprätthålls.

Determinismgarantier#

Motorn har ingen väggklocka, inget beroende av exekveringstråd och ingen oseedad slumpmässighet. Varje stokastisk process drivs av en ChaCha8Rng-ström som styrs av scenariots seed och dras i fast ordning. Följder:

Egenskap Garanteras Upprätthålls av
Samma scenario, samma maskin → byte för byte identisk result.json Ja scripts/check-reproducible.sh (kör referensscenariot två gånger och jämför SHA-256 (SHA: Secure Hash Algorithm))
Samma scenario → identiska kvalitetsmått fält för fält Ja, per plattform tests/golden.rs fastlåser varje kvalitetsmått (FoM) för de fyra referensscenarierna
Scenariots indatahash (scenario_hash) är plattformsoberoende Ja innehållsadresserad SHA-256 av det kanoniska scenariot, fastlåst i tests/golden.rs
Indatafingeravtryck + utdatans form identiska över operativsystem Ja tests/cross_platform_golden.rs fastlåser en exakt SHA-256 per scenario (tio scenarier, en .sha256-fil var i tests/golden/), kontrollerad på CI-matrisen (kontinuerlig integration) med 3 operativsystem
Utdatans värden stämmer överens mellan operativsystem (ubuntu/macOS/Windows) Ja, till 1e-6 CI-jobbet reproducibility-matrix kör golden.rs (1e-6), sgp4_verification.rs (2e-5 km) och determinism.rs på alla tre operativsystem
En navigeringsmeddelanderam för låg omloppsbana (LEO) är samma byte på varje plattform och i varje bygge, WebAssembly-bygget (WASM) inräknat Ja src/portable_math.rs (varje transcendent funktion och varje normalavvikelse i typen leo-navmsg går genom det rena Rust-cratet libm); leo_navmsg::tests::the_encoded_frame_is_the_same_bytes_on_every_platform fastlåser en hel ram utan plattformsspärr
Seedade indexdragningar (bootstrap-omsampling, blandningar) är desamma på 32-bitars och 64-bitars mål Ja portable_math::uniform_index samplar alltid som u64; fastlåst i portable_math::tests
Samma verktygskedja överallt Ja rust-toolchain.toml fastlåser kanalen; scripts/check-toolchain.sh låter bygget misslyckas vid avvikelse; CI och utgåva fastlåser samma version
Samma beroendeuppsättning Ja Cargo.lock är incheckad och cargo metadata --locked används för SBOM (software bill of materials)

Varje körning från kommandoraden skriver också en reproducerbarhetspost i sin rapport (<scenario>.report.json och .report.html): motorversionen, SHA-256 för scenariofilen och för resultatdokumentet, fröet, plattformen och det exakta kommandot, som tests/advanced_report_cli.rs kör om till ett byte för byte identiskt resultat. Rapporten är själv en ren funktion av körningen: två körningar av scenarios/clock-holdover.toml skriver samma report.json byte för byte. Se REPORTS.md.

Förbehållet mellan plattformar (och hur goldens hanterar det)#

De numeriska resultaten är bitvis identiska på en given plattform men kan skilja sig i de sista enheterna i sista siffran (ULP) mellan plattformar. Orsaken är plattformens matematikbibliotek: sqrt, ln, exp med flera måste enligt IEEE-754 (IEEE: Institute of Electrical and Electronics Engineers) inte vara korrekt avrundade, så Linux (glibc, GNU C-biblioteket), macOS och Windows kan var och en ge en annan sista bit. Under en lång körning ackumuleras dessa skillnader på ~1e-16 till kanske ~1e-12 relativt.

Två saker gör att skillnaden i sista siffran blir större än den börjar, och båda är uppmätta snarare än antagna. En adaptiv integrator väljer sitt nästa steg utifrån felskattningen genom en femterot, så en enhet i sista siffran ändrar stegföljden och de två plattformarna stämmer då bara överens till integrationstoleransen. En iterativ skattare (en minstakvadratanpassning, ett filter för banbestämning) kan ta en annan väg till konvergens. Typer som bygger på någon av dem kan skilja sig mellan plattformar med mer än 1e-6 i enskilda fält; src/test_support.rs registrerar samma förhållande för enhetstesterna.

Byggprofilen spelar roll på samma sätt, på en och samma maskin. Ett optimerat bygge på macOS slår ihop en sinus och en cosinus av samma argument till ett enda anrop av systemets kombinerade rutin, vars sinus skiljer sig från den fristående sin i sista biten för 379 av 200 000 argument; ett ooptimerat bygge gör de två anropen. Uppmätt på aarch64 macOS över de 138 scenariofilerna ger ett debug- och ett release-bygge av samma källkod byte för byte identiska resultatdokument för 102. De övriga 36 skiljer sig i de sista siffrorna: 28 inom 1e-6, ett (leo-ppp-convergence) med 2.8e-6, och sju kampanjer bara i kontrollsummorna för sina medlemskörningar; ingen skiljer sig i en etikett, ett antal eller ett utlåtande. Garantin om byte för byte-identitet ovan gäller därför ett bygge: samma binär två gånger.

De seedade normaldragningarna är en tredje, mycket sällsyntare källa: samplaren anropar värdens exponential- och logaritmfunktion i sina sällsynta grenar, och ungefär en dragning på en miljon skiljer sig i sista biten mellan det inbyggda och WASM-bygget.

Där en utdata är diskret är en skillnad i sista siffran inte acceptabel alls, och typen beräknas med src/portable_math.rs istället för värdbiblioteket. Typen leo-navmsg är den första: dess binära ram är överförda heltal, och samma scenario kodades en gång till tre olika ramar: i ett release-bygge, i ett debug-bygge av samma källkod och i webbläsaren. Det är nu samma byte i alla tre.

På grund av detta fastlåser golden-testerna inte en enda hash över plattformar av flyttalsutdata — det skulle vara bräckligt och skulle få ärligt korrekta byggen på ett annat operativsystem att misslyckas. Istället:

  • tests/golden.rs fastlåser varje kvalitetsmått med en relativ tolerans på 1e-6 — fyra storleksordningar snävare än någon verklig regression (som flyttar ett värde med hela procent) men långt mer tillåtande än jitter i matematikbiblioteket (libm) mellan plattformar. Rutnätsbundna fält (holdover-sekunder) och fält som är exakt noll fastlåses exakt.
  • scenario_hash — en innehållshash av indata — är plattformsoberoende och fastlåses exakt.
  • tests/cross_platform_golden.rs fastlåser en exakt SHA-256, incheckad per scenario i tests/golden/, över den projektion som är identisk mellan plattformar: indatafingeravtrycket plus utdatans form (fältnamn, nästling, bladtyper, arraylängder — fastlagda av deterministisk rutnätsaritmetik, aldrig flyttalsvärdena). Det fångar strukturella regressioner exakt medan toleransfastlåsningarna ovan fångar värderegressioner.
  • scripts/check-reproducible.sh upprätthåller byte för byte identisk utdata mellan två körningar på samma maskin (determinismgarantin).
  • CI-jobbet reproducibility-matrix kör de fyra testerna ovan (cross_platform_golden, golden, determinism, sgp4_verification) på ubuntu-latest, macos-latest och windows-latest, så att reproducerbarhet mellan plattformar kontrolleras vid varje push — shape/input-goldens exakt, numeriken till 1e-6 och SGP4-tillstånden (Simplified General Perturbations 4) till 2e-5 km — istället för att förlita sig på ett enda operativsystem.

Om du behöver generera om de fastlåsta talen (till exempel efter en avsiktlig modelländring), kör varje referensscenario och kopiera de utskrivna FoM-värdena till tests/golden.rs, och notera sedan ändringen i CHANGELOG.md.

Software bill of materials (SBOM)#

scripts/gen-sbom.sh skapar en CycloneDX 1,5-SBOM som listar varje crate som ingår i en kshana-artefakt, med exakt version, källa och licens. Det är en beroendefri generator byggd på cargo metadata --locked (så den fungerar med enbart verktygskedjan), och den går igenom upplösningsgrafen från paketet kshana via enbart normala beroenden och byggberoenden. Utvecklingsberoenden (crates som bara används i test, till exempel sgp4) utesluts eftersom ingen artefakt innehåller dem.

Grafen är unionen av de funktionsuppsättningar som de levererade artefakterna byggs med: standardbygget (biblioteket och CLI (kommandoradsgränssnitt)), --features python (PyPI (Python Package Index)-hjulet, vars pyo3-kedja är dess gräns mot främmande funktioner) och --features wasm (npm-paketet, som bär samma SBOM i sin tarball). Plattformsvillkorade beroenden för varje mål ingår, eftersom hjulen levereras för flera operativsystem och npm-paketet riktar sig mot WebAssembly. Ett dokument täcker alla tre artefakterna, så för en enskild av dem är det en övermängd. Det listar för närvarande 107 komponenter; antalet är fastlåst i tests/fixtures/reproducibility_software_assurance/. Den fristående servern kshana-mcp har ett eget manifest och beskrivs inte av den här SBOM:en.

Utdata är deterministisk — samma beroendeuppsättning ger ett byte för byte identiskt dokument, inklusive ett serienummer som härleds från den sorterade paketlistan istället för från en tidsstämpel.

Utgivningsarbetsflödet genererar SBOM:en (kshana-sbom.cdx.json) och bifogar den till varje taggad utgåva; publiceringsarbetsflödet levererar den också bredvid PyPI-hjulen och inuti npm-paketet.

Byggprovenans#

Utgivningsarbetsflödet producerar ett byggprovenansintyg enligt SLSA (Supply-chain Levels for Software Artifacts) (actions/attest-build-provenance) som täcker varje fil det bifogar till GitHub Release: kommandoradsbinärerna för varje plattform, serverbinären kshana-mcp, SBOM:en, valideringssammanfattningen och SHA256SUMS. En konsument kan med gh attestation verify verifiera att artefakterna byggdes av det här repositoriets utgivningsarbetsflöde från den här källkoden — vilket stänger glappet mellan "här är en binär" och "här är en binär som jag kan spåra till dess källkod". Till exempel för SBOM:en för 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