SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-21

Reproducible builds वास्तव में क्या सिद्ध करते हैं?

Checksum केवल यह बताता है कि फाइल सही तरीके से डाउनलोड हुई है। Reproducible builds यह सुनिश्चित करते हैं कि बाइनरी कोड आपके द्वारा पढ़े गए सोर्स कोड से ही बनी है।

Reproducible builds क्या सिद्ध करते हैं

Reproducible builds केवल एक सीमित तथ्य सिद्ध करते हैं: जो binary आपको दी गई है, वह वही binary है जिसे इस सटीक source code से बनाया गया है। कोई भी व्यक्ति उसी source को लेकर उसे दोबारा build कर सकता है और bytes की तुलना कर सकता है। सत्यापन अब केवल publisher तक सीमित नहीं रह जाता है।

Reproducible Builds project इसे इस प्रकार परिभाषित करता है: "एक build reproducible तब होती है यदि समान source code, build environment और build instructions दिए जाने पर, कोई भी पक्ष सभी निर्दिष्ट artifacts की bit-by-bit समान प्रतियाँ फिर से बना सके।" तुलना की प्रक्रिया स्वयं एक hash है। सारी कठिनाई environment और instructions को इतना सटीक रूप से निर्धारित करने में है कि दो अलग-अलग मशीनें एक ही परिणाम पर सहमत हों।

Checksum इस प्रश्न का उत्तर क्यों नहीं देता है

प्रकाशित checksum यह सिद्ध करता है कि फाइल बिना किसी खराबी के प्राप्त हुई है। उस checksum पर लगा signature यह सिद्ध करता है कि वह उस व्यक्ति से आया है जिसके पास key है। इनमें से कोई भी यह नहीं बताता कि artifact के अस्तित्व में आने से पहले क्या हुआ था। यदि प्रकाशक की build machine breach हो गई है, तो malicious binary को भी ठीक वैसे ही checksum और sign किया जाता है जैसे किसी clean binary को, इसलिए downstream पर हर जांच सफल हो जाती है। यदि कोई maintainer ऐसे working tree से build करता है जिसे कभी push नहीं किया गया था, तो भी यही बात लागू होती है।

यही वह कमी है। आप source को पढ़ सकते हैं, signature को verify कर सकते हैं, checksum को verify कर सकते हैं, और फिर भी ऐसा code चला रहे हो सकते हैं जो कभी repository में दिखाई ही नहीं दिया। इसलिए, reproducibility published checksum के विरुद्ध download को verify करने से एक अलग विषय है। Checksum transfer की सुरक्षा करता है। Rebuild उस सब कुछ की सुरक्षा करता है जो transfer से पहले हुआ था।

यह हमला केवल सैद्धांतिक नहीं है। 2020 का SolarWinds Orion compromise ठीक इसी स्थिति में था: build system ने ऐसे signed artifacts जारी किए जो उस source से मेल नहीं खाते थे जिसे किसी ने review किया था। हर signature check सफल रहा, क्योंकि signatures artifact से शुरू होते हैं।

Reproducible build क्या सिद्ध नहीं करता है

यह वह हिस्सा है जिसे बढ़ा-चढ़ाकर बताया जाता है, इसलिए इसकी सीमाओं के बारे में सटीक रहें।

  • यह यह नहीं कहता कि source सुरक्षित है। खुले में commit किया गया backdoor भी reproducibly build होता है, और हर rebuilder इसकी पुष्टि करता है, क्योंकि वे सभी एक ही hostile source से build करते हैं। Reproducibility का लक्ष्य source tree पर स्थानांतरित हो जाता है। किसी को अभी भी उस tree को पढ़ना होगा, इसीलिए review policy, जिसमें open source projects में AI-assisted code के लिए नीतियां शामिल हैं, एक अलग नियंत्रण बनी रहती है।
  • यह यह नहीं कहता कि आपके inputs सुरक्षित हैं। Dependencies उस चीज़ का हिस्सा हैं जिसे आप build करते हैं। Build के समय resolve किया गया कोई malicious package artifact में compile हो जाता है, और हर rebuilder जो उसी dependency को resolve करता है, वह आपसे सहमत होता है। इसी तरह एक npm supply chain attack सर्वर तक पहुँचता है, और एक reproducible build उसे हूबहू reproduce कर देता है।
  • यह यह नहीं कहता कि toolchain ईमानदार है। यदि compiler के साथ समझौता किया गया है, तो उस compiler का उपयोग करने वाला हर rebuilder वही compromised output देता है, और सभी verdicts एकमत होते हैं। Reproducibility उस हमले की लागत बढ़ाती है। यह उसका पता नहीं लगाती है।
  • यह vulnerabilities के बारे में कुछ नहीं कहता। bit-for-bit reproduce की गई एक पुरानी library अभी भी अपनी प्रकाशित खामियों वाली एक पुरानी library ही है, इसलिए ज्ञात CVEs के लिए अपने सर्वर की जाँच अपने निर्धारित समय पर करते रहें।

Reproducibility जिस एक विशिष्ट attacker स्थिति को हटाती है, वह है: build machine, और source से binary तक का पूरा रास्ता। जब तक कोई package reproducible नहीं होता, तब तक publisher के बाहर कोई भी उस रास्ते का निरीक्षण नहीं कर सकता।

एक ही source से अलग-अलग bytes क्यों उत्पन्न होते हैं

अधिकांश software डिफ़ॉल्ट रूप से reproducible नहीं होते हैं, और इसके कारण सामान्य होते हैं। Compilers और archive formats उस मशीन के बारे में जानकारी रिकॉर्ड करते हैं जिस पर वे चलते हैं।

  • एक timestamp। tar, ar और zip formats फ़ाइल के modification times को स्टोर करते हैं, इसलिए अलग समय पर build करने से output फ़ाइल बदल जाती है।
  • एक path। Debug information absolute build directory को रिकॉर्ड करती है, इसलिए /home/alice/src में किया गया build और /build/pkg में किया गया build अलग-अलग होते हैं, भले ही code एक समान हो।
  • एक क्रम (ordering)। Directory को पढ़ने पर entries filesystem के क्रम में मिलती हैं, इसलिए मशीनों के बीच link line या archive member का क्रम बदल जाता है।
  • एक पहचान (identity)। Build scripts उस व्यक्ति का username, hostname या locale एम्बेड कर देती हैं जिसने उसे build किया है।
  • build के समय लिया गया निर्णय। CPU features का पता लगाना, या किसी चीज़ को रैंडम तरीके से seed करना, output को source के बजाय मशीन पर निर्भर बना देता है।

आप पहले कारण को लगभग दस सेकंड में घटित होते हुए देख सकते हैं:

mkdir -p /tmp/rb && cd /tmp/rb
echo hello > a.txt && tar cf one.tar a.txt
sleep 2
echo hello > a.txt && tar cf two.tar a.txt
sha256sum one.tar two.tar

दोनों hashes इसलिए अलग हैं क्योंकि tar header a.txt के modification time को स्टोर करता है, और फ़ाइल को फिर से लिखने से वह समय दो सेकंड आगे बढ़ गया। content byte-दर-byte समान है। Metadata को पिन करने से यह ठीक हो जाता है:

export SOURCE_DATE_EPOCH=1700000000
tar --sort=name --mtime="@${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -cf three.tar a.txt
touch a.txt
tar --sort=name --mtime="@${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -cf four.tar a.txt
sha256sum three.tar four.tar

अब hashes मेल खाते हैं, क्योंकि archive header का कोई भी field मशीन की वर्तमान स्थिति से नहीं आता है। --sort=name क्रम को ठीक करता है, --mtime घड़ी को ठीक करता है, और ownership flags आपके user id को रिकॉर्ड होने से रोकते हैं।

diffoscope के साथ अंतर पढ़ना

जब दो builds अलग होते हैं, तो sha256sum केवल यह बताता है कि वे अलग हैं, और कुछ नहीं। diffoscope यह बताने के लिए मौजूद है कि वे क्यों अलग हैं, और वह भी ऐसी भाषा में जिसे कोई भी पढ़ सके। यह दोनों पक्षों को recursively unpack करता है, binary formats को text में बदलता है, और फिर text की तुलना करता है। यह Debian packages, ELF binaries, tar और ZIP archives, PDFs, SQLite databases, और सौ से अधिक अन्य formats को संभाल सकता है।

sudo apt install -y diffoscope
diffoscope one.tar two.tar

ऊपर दिए गए tar pair के लिए report छोटी है। संक्षेप में, यह कुछ इस तरह दिखती है:

--- one.tar
+++ two.tar
├── file list
│ @@ -1 +1 @@
│ -rw-r--r-- 0/0  6 2026-08-18 10:14:02.000000 a.txt
│ +rw-r--r-- 0/0  6 2026-08-18 10:14:04.000000 a.txt

यह पूरा निदान है: समान आकार, समान path, समान permissions, लेकिन modification time अलग है। एक वास्तविक package बहुत लंबी report तैयार करता है, इसलिए इसे file में लिखें और browser में खोलें:

diffoscope --html report.html build1.changes build2.changes

जब inputs समान होते हैं तो diffoscope 0 exit code देता है, अलग होने पर 1, और समस्या आने पर 2 देता है। इसलिए, यह बिना किसी wrapper script के सीधे CI job में इस्तेमाल किया जा सकता है। एक छोटे VPS पर, diffoscope के बजाय diffoscope-minimal install करें: full package बहुत सारे ऐसे format helpers को install कर देता है जिनकी आपको शायद कभी जरूरत न पड़े।

SOURCE_DATE_EPOCH क्या ठीक करता है, और इसकी सीमाएं क्या हैं

SOURCE_DATE_EPOCH एक environment variable है जिसमें एक संख्या होती है: source के अंतिम modification का समय, जिसे 1 January 1970 UTC से सेकंड में गिना जाता है। जो build tool इसका पालन करता है, वह उस संख्या का उपयोग वहां करता है जहां उसे अन्यथा operating system से वर्तमान समय पूछना पड़ता। इसे version control से सेट करें, ताकि यह मान build के बजाय source के साथ चले:

export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)

Debian package में, debhelper आपके लिए changelog से इसे export कर देता है। debian/rules में इसे मैन्युअल रूप से सेट करना इस तरह दिखता है:

export SOURCE_DATE_EPOCH ?= $(shell dpkg-parsechangelog -STimestamp)

इसका support हर tool के लिए अलग होता है, यह global नहीं है। cmake 3.8 और उसके बाद के वर्ज़न, gcc 7 और उसके बाद के वर्ज़न, rpm 4.13 से ऊपर और Docker buildx 0.10 और उसके बाद के वर्ज़न इसे पढ़ते हैं। आपकी अपनी scripts इसे तब तक नहीं पढ़ेंगी जब तक आप उन्हें ऐसा करने के लिए नहीं लिखते। यदि कोई script date को कॉल करती है, तो उसे यह variable दें:

BUILD_DATE="$(date --utc --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y-%m-%d)"

इसे लागू करते समय एक नियम महत्वपूर्ण है। यदि variable पहले से सेट है, तो आपके build के लिए वही मान वर्तमान समय है, इसलिए caller द्वारा दिए गए मान को कभी न बदलें।

Container images में यही समस्या एक अलग wrapper में होती है। Docker buildx 0.10 और उसके बाद के वर्ज़न आपके shell से SOURCE_DATE_EPOCH को build argument के रूप में build में पास करते हैं। layers के अंदर की फाइलों के timestamps को rewrite करने के लिए exporter की आवश्यकता होती है, जिसे BuildKit ने 0.13 में जोड़ा था, और इसका documented तरीका परिणाम को registry में push करता है:

export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
docker buildx build --output type=image,name=registry.example.com/app:1.0,push=true,rewrite-timestamp=true .

reprotest के साथ अपने खुद के build का परीक्षण करना

reprotest एक ही source को दो बार build करता है और दोनों builds के बीच जानबूझकर environment में बदलाव करता है, फिर परिणामों की तुलना करता है। ये बदलाव ही इसका मुख्य उद्देश्य हैं। डिफ़ॉल्ट रूप से, यह build path, समय, timezone, locale, umask, hostname, user और group, CPUs की संख्या, home directory और फ़ाइल क्रम में बदलाव करता है।

sudo apt install -y reprotest
reprotest . -- null

-- के बाद का सब कुछ build environment backend का चयन करता है, और null का अर्थ है वह system जिस पर आप अभी काम कर रहे हैं। निरीक्षण के लिए temporary directories को बनाए रखने के लिए -vv -d जोड़ें, जैसा कि reprotest . -vv -- null -d में दिखाया गया है। यह पता लगाने के लिए कि यह किस प्रकार का source tree है, reprotest auto -- null का उपयोग करें।

कुछ बदलावों के लिए विशेषाधिकारों (privileges) या अतिरिक्त packages की आवश्यकता होती है, और जब वे नहीं चल पाते हैं तो वे स्पष्ट रूप से विफल हो जाते हैं। पूरी प्रक्रिया को root के रूप में चलाने के बजाय उन्हें बंद कर दें:

reprotest --vary=-user_group,-domain_host,-fileordering auto -- null

reprotest जो कुछ भी रिपोर्ट करता है, वह ऐसी चीज़ है जिसे एक rebuilder बाद में सार्वजनिक रूप से आपके project के नाम के साथ रिपोर्ट करेगा।

Rebuilder verdict का क्या अर्थ है

Rebuilder एक ऐसी मशीन है जो publisher की नहीं होती। यह प्रकाशित source और रिकॉर्ड किए गए build environment को लेती है, package को फिर से build करती है, और अपने output की तुलना archive में मौजूद artifact से करती है। यह verdict केवल इसलिए महत्वपूर्ण है क्योंकि मशीन स्वतंत्र है।

Debian environment को एक .buildinfo फ़ाइल में रिकॉर्ड करता है जिसे dpkg-buildpackage, .deb के बगल में लिखता है। इसके fields सबसे महत्वपूर्ण हिस्सा हैं। Installed-Build-Depends उन सभी installed packages की सूची देता है जो build को प्रभावित कर सकते हैं, उनके सटीक versions के साथ। Build-Path यह रिकॉर्ड करता है कि build कहाँ चला था। Environment उन environment variables को रिकॉर्ड करता है जिनका प्रभाव पड़ता है। Checksums-Sha256 outputs को कवर करता है। वह फ़ाइल दूसरे प्रयास के लिए एक recipe है:

sudo apt install -y devscripts mmdebstrap
debrebuild --buildresult=./artifacts --builder=mmdebstrap hello_2.10-2_amd64.buildinfo

debrebuild buildinfo को पढ़ता है और उसमें बताए गए सटीक dependency versions को snapshot.debian.org से खींचता है, ताकि आज का rebuild उन package versions का उपयोग कर सके जो मूल build के दिन मौजूद थे। mmdebstrap builder को किसी chroot setup या superuser अधिकारों की आवश्यकता नहीं होती है। diffoscope का उपयोग करके इसके द्वारा उत्पादित artifacts की तुलना archive copy से करें।

Arch Linux rebuilderd चलाता है, जो इसे लगातार करता है और verdicts प्रकाशित करता है:

rebuildctl -H https://reproducible.archlinux.org pkgs ls --name rebuilderd

Statuses GOOD, BAD और UNKWN हैं, और प्रत्येक का सामान्य अर्थ अलग-अलग दिशाओं में गलत है। GOOD का अर्थ है कि एक स्वतंत्र पक्ष को वही bytes मिले, जो build के बारे में एक मजबूत बयान है लेकिन source के बारे में कोई बयान नहीं है। BAD लगभग कभी भी हमला नहीं होता है: इसका सामान्य कारण timestamp या कोई path होता है जिसे packaging पिन करने में विफल रही, यही कारण है कि rebuilderd विफलता के साथ एक diffoscope रिपोर्ट संलग्न कर सकता है। UNKWN का अर्थ है कि किसी ने इसका परीक्षण नहीं किया है, और एक untested package एक passing package नहीं होता है।

इसलिए operational नियम संक्षिप्त है। BAD verdict रिपोर्ट पढ़ने का एक कारण है। यदि रिपोर्ट timestamps, build paths या member ordering दिखाती है, तो packaging bug फ़ाइल करें। यदि यह बिना किसी स्पष्टीकरण के अलग executable code दिखाती है, तो उस build को deploy करना बंद करें और इसे escalate करें।

Debian अभी कितना reproducible है?

ChartDebian packages reproducible in the test framework, amd64
The data behind this chart
[
  {
    "label": "unstable",
    "percent_reproducible": 94.2,
    "tested_count": "41,163"
  },
  {
    "label": "forky",
    "percent_reproducible": 93.4,
    "tested_count": "39,059"
  },
  {
    "label": "experimental",
    "percent_reproducible": 67.0,
    "tested_count": "588"
  }
]

इस पोस्ट को लिखे जाने के दिन, amd64 पर unstable शाखा में कुल 41,163 पैकेजों में से 94.2% पैकेज reproducible थे। Experimental शाखा में यह आंकड़ा 67.0% था, जो 588 पैकेजों के बहुत छोटे और नए नमूने पर आधारित है; यह उन पैकेजों के लिए अपेक्षित है जिन्हें अभी तक ठीक नहीं किया गया है।

ये आंकड़े tests.reproducible-builds.org पर मौजूद Debian पेज से लिए गए हैं। इन्हें 2026-08-18 को देखा गया था, जब पेज पर "Last update: 2026-08-18 16:02 UTC" का स्टैम्प था। ये आंकड़े बदलते रहते हैं। छह महीने बाद इस पैराग्राफ को उद्धृत करने के बजाय सीधे ट्रैकर को देखें।

प्रतिशत से अधिक एक चेतावनी महत्वपूर्ण है। यह फ्रेमवर्क प्रत्येक पैकेज को अपने हार्डवेयर पर दो बार बिल्ड करता है, दोनों बिल्ड के बीच वातावरण में बदलाव करता है, और फिर दोनों परिणामों की तुलना करता है। यह मापता है कि क्या कोई पैकेज reproducibly बिल्ड हो सकता है। यह इस बात की जाँच नहीं है कि आर्काइव में मौजूद .deb प्रकाशित आर्टिफैक्ट से मेल खाता है या नहीं; यह एक rebuilder का अलग काम है जो प्रकाशित आर्टिफैक्ट के साथ तुलना करता है। दोनों संख्याएँ उपयोगी हैं। वे अलग-अलग सवालों के जवाब देती हैं, और लोग पहली संख्या को ऐसे उद्धृत करते हैं जैसे वह दूसरी हो।

अपने सर्वर पर क्या करें

आप किसी distribution को फिर से नहीं बना रहे हैं। जो हिस्से एक सामान्य सर्वर पर स्थानांतरित होते हैं, वे छोटे और सस्ते होते हैं।

  • toolchain को पिन करें। tag द्वारा संदर्भित base image बिना किसी चेतावनी के बदल सकती है। इसे digest द्वारा संदर्भित करें, और release के साथ digest को रिकॉर्ड करें।
  • inputs को रिकॉर्ड करें। lockfile, image digest और compiler version को artifact के साथ रखें। जिस build के environment को आप फिर से नहीं बना सकते, उसे दोबारा तैयार नहीं किया जा सकता, इसलिए उसकी कभी भी जाँच नहीं की जा सकती।
  • CI में दो बार build करें और outputs अलग होने पर job को fail कर दें। इसमें एक अतिरिक्त build का खर्च आता है, लेकिन यह nondeterminism को उसी दिन पकड़ लेता है जिस दिन कोई इसे पेश करता है, न कि एक साल बाद किसी incident के दौरान।
  • compiler द्वारा embed किए गए paths को हटा दें। Go के लिए, go build -trimpath -buildvcs=false build directory और version control stamp को हटा देता है, और go version -m ./app यह print करता है कि binary में वास्तव में क्या गया है।
  • जो आपने deploy किया है उसका hash रखें। जब आपको यह जानने की आवश्यकता हो कि चल रही binary किसी source revision से मेल खाती है या नहीं, तो वह रिकॉर्ड ही एकमात्र ऐसी चीज है जो उत्तर दे सकती है।

CI check चार लाइनों का है:

set -eu
./build.sh && mv dist/app app.1
./build.sh && mv dist/app app.2
diffoscope --text - app.1 app.2

जब दो artifacts अलग होते हैं तो diffoscope non-zero exit देता है, इसलिए job अपने आप fail हो जाती है और log में एक पठनीय स्पष्टीकरण छोड़ देती है। यही पूरा विचार है, जिसे एक repository तक सीमित किया गया है: यह दावा कि एक binary एक source tree से आती है, ऐसी चीज होनी चाहिए जिसे दूसरी machine जांच सके।

FAQ

क्या reproducible build का मतलब यह है कि सॉफ्टवेयर सुरक्षित है?

नहीं। यह केवल यह सिद्ध करता है कि बाइनरी सोर्स कोड के अनुरूप है, इससे अधिक कुछ नहीं। यदि पब्लिक सोर्स ट्री में कोई बैकडोर शामिल है, तो वह भी reproducible तरीके से बिल्ड होगा, और हर रीबिल्डर इसकी पुष्टि करेगा, क्योंकि उन सभी ने एक ही हानिकारक सोर्स से बिल्ड किया है। एक ज्ञात CVE वाला पैकेज पूरी तरह से रिप्रोड्यूस हो सकता है और असुरक्षित बना रह सकता है। रिप्रड्यूसिबिलिटी एक हमलावर की स्थिति को हटाती है, जो कि बिल्ड मशीन और सोर्स से बाइनरी तक का रास्ता है। सोर्स को पढ़ना और कमजोरियों (vulnerabilities) को ट्रैक करना अलग काम हैं, जो रिप्रड्यूसिबिलिटी आपके लिए नहीं करती है।

सोर्स में कुछ भी न बदलने पर भी मेरे दो बिल्ड अलग क्यों होते हैं?

इसका कारण लगभग हमेशा टाइमस्टैम्प, पाथ या क्रम (ordering) होता है। tar और zip जैसे आर्काइव फॉर्मेट फाइल मॉडिफिकेशन टाइम को स्टोर करते हैं, इसलिए अलग-अलग समय पर किए गए चेकआउट से अलग बाइट्स उत्पन्न होते हैं। डीबग जानकारी में एब्सोल्यूट बिल्ड डायरेक्टरी रिकॉर्ड होती है, इसलिए /home/alice/src और /build/pkg एक ही कोड से अलग-अलग बाइनरी उत्पन्न करते हैं। डायरेक्टरी रीड फाइलसिस्टम के क्रम में एंट्रीज लौटाती हैं, इसलिए लिंक लाइन पर ऑब्जेक्ट फाइलों का क्रम दूसरी मशीन पर अलग हो सकता है। diffoscope build1 build2 चलाएं और रिपोर्ट आपको बताएगी कि इनमें से कौन सा कारण है, बजाय इसके कि आप अनुमान लगाते रहें।

SOURCE_DATE_EPOCH क्या है और क्या मुझे इसे सेट करना होगा?

यह एक मानक एनवायरनमेंट वेरिएबल है जिसमें एक नंबर होता है: सोर्स का अंतिम मॉडिफिकेशन समय, 1 जनवरी 1970 UTC से सेकंड में। जो टूल्स इसका सम्मान करते हैं, वे उस वैल्यू का उपयोग वहां करते हैं जहां वे अन्यथा सिस्टम क्लॉक को पढ़ते। इसे वर्जन कंट्रोल से export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) के साथ सेट करें। यह स्वचालित नहीं है और यह कोई सामान्य समाधान नहीं है। केवल वही टूल्स इसे पढ़ते हैं जिन्होंने इसे लागू किया है, और आपकी अपनी बिल्ड स्क्रिप्ट्स को इसे स्वयं पढ़ना होगा, इसलिए जो स्क्रिप्ट date को कॉल करती है, वह तब तक वर्तमान समय को स्टैम्प करती रहेगी जब तक आप उसे बदल नहीं देते।

जब कोई रीबिल्डर BAD रिपोर्ट करे तो मुझे क्या करना चाहिए?

कुछ भी करने से पहले रिपोर्ट पढ़ें। BAD वर्डिक्ट का मतलब है कि एक स्वतंत्र रीबिल्ड ने समान बाइट्स उत्पन्न नहीं किए, और इसका सामान्य कारण हमले के बजाय पैकेजिंग में नॉन-डिटरमिनिज्म (nondeterminism) होता है। rebuilderd इसी कारण से diffoscope रिपोर्ट जनरेट कर सकता है। यदि अंतर टाइमस्टैम्प, बिल्ड पाथ या फाइल ऑर्डरिंग में है, तो यह एक पैकेजिंग बग है जिसे रिपोर्ट किया जाना चाहिए। यदि अंतर बिना किसी स्पष्टीकरण के एग्जीक्यूटेबल कोड में है, तो उस बिल्ड को डिप्लॉय करना बंद करें, आर्टिफैक्ट्स को सुरक्षित रखें और इसे पब्लिशर तक पहुंचाएं।

#reproducible-builds#supply-chain#diffoscope#debian#verification