روی لپ‌تاپ توسعه‌دهنده ۷۲ Check از ۷۲ Check سبز است. همان Commit با Tag ظاهراً یکسان در محیط تست اجرا می‌شود؛ هر شش Container هم «Running» هستند، اما Callback سفارش تکراری می‌شود. کدام طرف درست می‌گوید؟ پاسخ حرفه‌ای «ماشین من» یا «محیط شما» نیست. باید دو اجرای مشخص را با Build و Artifact ثابت، Environment Fingerprint قابل‌مقایسه، Deltaهای رتبه‌بندی‌شده و آزمایش کنترل‌شده بررسی کرد.

این راهنما برای جست‌وجوی «روی ماشین من کار می‌کند» یک خروجی عملی می‌دهد: Environment Delta Reproduction Protocol. این پروتکل Observation را از تفسیر جدا می‌کند، تفاوت محیط را به فرضیه‌ی علّی تبدیل نمی‌کند، یک متغیر را در هر آزمایش تغییر می‌دهد و نتیجه را با Evidence Manifest به تصمیم بعدی می‌رساند.

پاسخ کوتاه: «روی ماشین من کار می‌کند» یعنی چه؟

این جمله فقط یک Observation محدود به یک Run است: یک Subject مشخص، با یک Build مشخص، در یک Environment و State مشخص، در زمانی مشخص، نتیجه‌ی مورد انتظار را داده است. این مشاهده نه Failure محیط دیگر را باطل می‌کند، نه اثبات می‌کند دو طرف همان Artifact را اجرا کرده‌اند، نه علت اختلاف را نشان می‌دهد.

عبارتآنچه واقعاً می‌دانیمآنچه هنوز نمی‌دانیم
«اینجا Pass شد»یک Attempt در Context گزارش‌شده Pass شدهتکرارپذیری، Artifact یکسان و نمایندگی Context
«آنجا Fail شد»یک Failure در Target مشاهده شدهDefect محصول، محیط، Testware یا Expected variance
«نسخه یکی است»احتمالاً Label یا Commit برابر استبایت‌های Artifact، Build provenance و Runtime inputs
«Containerها بالا هستند»Processها احتمالاً Running هستندReadiness، Dependency، Data، Oracle و رفتار درست

مالکیت این مقاله و مرز با راهنماهای نزدیک

اگر هدف شما طراحی Cloud/Container/IaC و Fidelity است، معماری محیط تست مدرن را بخوانید. برای تحویل و Readyکردن یک محیط، چک‌لیست راه‌اندازی Test Environment مالک موضوع است. برای عیب‌یابی فرمان‌های Compose، لَب Docker Compose برای تسترها و برای ساخت خود Report، گزارش باگ قابل بازتولید را ببینید. این صفحه فقط فاصله‌ی بین دو Run ناسازگار را مدیریت می‌کند.

مسئلهمالکخروجی
چه محیطی بسازیم؟Environment Architecture/SetupEnvironment Contract و Readiness
چگونه Failure را گزارش کنیم؟Bug ReportReproduction Contract و Evidence
چرا دو Run فرق دارند؟همین مقالهFingerprint، Delta، Experiment و Disposition
چگونه Pipeline را پیاده کنیم؟CI/CD GuidePipeline، Artifact و Run Manifest

اصل اول: Run را مقایسه کنید، نه آدم‌ها و ماشین‌ها را

«ماشین توسعه‌دهنده» یک هویت فنی نیست. لپ‌تاپ ممکن است میان دو Attempt آپدیت شود، Cache بماند، Flag تغییر کند یا Dependency بیرونی پاسخ دیگری بدهد. واحد مقایسه باید Source Run و Target Run باشد؛ هرکدام با شناسه، زمان، Build، Artifact، Test، Data و Environment Snapshot.

  • Source Run لزوماً «درست» یا Baseline معتبر نیست؛ فقط Control پیشنهادی است.
  • Target Run لزوماً «خراب» نیست؛ فقط Witness Failure است.
  • Developer، Tester و Ops نقش Evidence Producer دارند، نه متهم.
  • نتیجه‌ی یک Attempt را به همه‌ی Buildها، داده‌ها یا کاربران تعمیم ندهید.
  • Clock، Locale و Feature Flag بخشی از Context هستند، نه حاشیه‌ی گزارش.

Observation، Interpretation، Hypothesis و Cause را جدا کنید

نوعنمونه‌ی سالمخطای رایج
Observationدر RUN-T-۲۹، Event دوم HTTP ۲۰۰ گرفت و دو Ledger entry دیده شد«محیط تست مشکل دارد»
InterpretationOracle ثبت دو Entry را خلاف قاعده‌ی Idempotency می‌داندتبدیل برداشت به واقعیت خام
HypothesisFlag متفاوت ممکن است مسیر Dedup را غیرفعال کرده باشداعلام Root cause پیش از آزمایش
Cause claimفقط پس از Intervention و Controlهای کافینسبت‌دادن هر Delta به Failure

زنجیره‌ی هویت را پیش از Debug ثابت کنید

مقایسه‌ی دو Environment بدون Identity Chain به حدس تبدیل می‌شود. نام نسخه برای انسان مفید است، اما شناسه‌ی کافی نیست. Repository/Commit باید به Build، Build به Artifact digest، Artifact به Release/Deployment و هر Deployment به Environment/Run متصل شود.

Program/Product → Repository/Commit → Build/Provenance
→ Artifact/Digest → Release/Deployment → Environment/Fingerprint
→ Test/Data/Oracle → Run/Attempt → Observation/Evidence

در OCI، Digest یک Content identifier مبتنی بر Hash برای بایت‌های محتوا است؛ مرجع فنی: OCI Image Descriptor. این ویژگی برای تشخیص Artifact بسیار مهم است، اما برابری Digest به‌تنهایی Config، Secret reference، Data، DNS، Kernel، Clock یا Dependency خارجی را برابر نمی‌کند.

Commit، Version، Tag و Digest یک چیز نیستند

شناسهچه چیزی را نام می‌دهد؟محدودیت
Commit IDSnapshot کد در RepositoryBuild inputهای بیرونی یا بایت خروجی را کامل نمی‌گوید
Version/Release labelنام قراردادی برای انسان و فرایندممکن است بازاستفاده یا اشتباه برچسب‌گذاری شود
Image tagReference قابل‌خواندنمی‌تواند به Manifest دیگری حرکت کند
Artifact digestهویت محتوایی Artifactرفتار Runtime و ورودی‌های بیرونی را تضمین نمی‌کند
Deployment IDعمل استقرار مشخصبدون Manifest نمی‌گوید چه چیز مستقر شد

Docker نیز Pinکردن Base image با digest را برای Build reproducible توصیه می‌کند؛ نمونه‌ی Policy رسمی در Docker Build Policies آمده است. «Reproducible build» در این Context را با «رفتار یکسان در هر Environment» یکی نگیرید.

Build Provenance چه چیزی می‌دهد و چه چیزی نمی‌دهد؟

Provenance می‌تواند Builder، ورودی‌ها، پارامترها و فرایند تولید Artifact را قابل‌ردیابی کند. SLSA آن را اطلاعات قابل‌تأیید درباره‌ی محل، زمان و چگونگی تولید Artifact تعریف می‌کند؛ مرجع: SLSA Provenance. Provenance قوی، سؤال «این Artifact از کجا آمد؟» را بهتر پاسخ می‌دهد؛ سؤال «چرا این Run Fail شد؟» همچنان به Runtime Fingerprint و Evidence نیاز دارد.

Build Identity
buildId: BUILD-SYN-29
commitId: abc1234
builderId: BUILDER-SYN-29
artifactDigest: sha256:synthetic29
baseImageDigest: sha256:base-synthetic29
dependencyLockDigest: sha256:lock-synthetic29
provenanceRef: PROV-SYN-29

Environment Fingerprint چیست؟

Fingerprint یک Snapshot نسخه‌دار و کمینه از ویژگی‌هایی است که ممکن است برای Quality Question حاضر معنا داشته باشند. هدف آن Dumpکردن کل سیستم نیست. هر Field باید نام، نوع، روش جمع‌آوری، زمان، حساسیت، Redaction و نسخه‌ی Collector داشته باشد. مقدار Secret را ثبت نکنید؛ فقط Reference/version یا Digest ایمن را، اگر Policy اجازه می‌دهد، نگه دارید.

EnvironmentFingerprint {
  environmentId, capturedAt, collectorVersion,
  os, kernel, architecture, runtime,
  imageDigest, entrypoint, dependencyLockDigest,
  configSchemaVersion, configKeySetDigest, featureFlagSnapshot,
  locale, timezone, clockSource,
  networkPolicy, dnsView, dependencyEndpointSet,
  dataSnapshotId, schemaVersion,
  redactionPolicy, digest
}

ابعاد Fingerprint را بر اساس سؤال انتخاب کنید

بُعدنمونه Fieldچه Failureهایی را توضیح نمی‌دهد؟
Artifactimage/artifact digest، entrypointData و Dependency بیرونی
PlatformOS، Kernel، Arch، RuntimeFeature behavior ناشی از Config
ConfigSchema، Key-set digest، Flag snapshotState پنهان در DB/Cache
Time/LocaleTimezone، Clock source، LocaleNetwork partition
NetworkDNS view، Proxy policy، endpoint setمحتوای پاسخ Dependency
Data/StateSnapshot ID، Schema، Seed lineageRace غیرقطعی
ObservabilityTrace sampling، log schema، metric versionرفتار واقعی اگر Instrumentation ناقص باشد

Config را بدون افشای Secret مقایسه کنید

Copyکردن `.env` یا الصاق کامل Configuration به Ticket ممکن است Credential، Token یا داده‌ی حساس را منتشر کند. برای مقایسه، ابتدا Schema و Set کلیدها، منبع Resolution، Version و Presence را بسنجید؛ مقدارهای حساس باید با سیاست مشخص Redact شوند. Equality یک Hash هم فقط Equality ورودی Canonicalشده را نشان می‌دهد، نه مناسب‌بودن مقدار.

Fieldقابل ثبتنباید ثبت شود
DB credentialsecretRef + version + resolved/presentPassword یا Connection string کامل
Feature flagنام غیرحساس، Variant، snapshot IDRule حاوی شناسه‌ی کاربر واقعی
EndpointService alias و Contract versionToken یا Query حساس
Config setCanonical key-set digestDump بی‌مرز همه‌ی Environment variables

Data و State معمولاً Delta پنهان‌اند

Database schema برابر، State برابر نیست. Seed، Migration history، Cache، Queue backlog، Object storage، Search index، Session و Clock-dependent record می‌توانند رفتار را تغییر دهند. برای طراحی Data امن و نماینده، راهنمای داده‌ی تست واقعی یا مصنوعی را ببینید. Production data پیش‌فرض یا شرط بازتولید نیست.

  • Data snapshot را با ID، Schema، Seed و زمان Freeze معرفی کنید.
  • State reset را بخشی از Procedure بدانید، نه کار شفاهی قبل از تست.
  • Queue و Cache را بدون ثبت Evidence پاک نکنید؛ ممکن است Witness را نابود کند.
  • برای Race، Attemptهای متعدد و Timeline لازم است.
  • کمینه‌سازی داده باید Invariantهای لازم برای Failure را حفظ کند.

Time، Timezone، Locale و Encoding را جدی بگیرید

در نرم‌افزار فارسی، UTC instant، نمایش Asia/Tehran، تاریخ جلالی نمایشی، ارقام فارسی/عربی/لاتین، جداکننده‌ی هزارگان، IRR در برابر نمایش تومان، Unicode normalization و RTL/LTR می‌توانند مسیرهای متفاوتی بسازند. تاریخ جلالی را Source of truth زمانی نکنید؛ Instant و Offset را جدا ذخیره کنید. تومان را Currency code جا نزنید؛ اگر فقط نمایش است، صریح برچسب بزنید.

Canonical test value (fictional)
instant: 2026-08-13T03:30:00Z
viewTimezone: Asia/Tehran
presentationCalendar: jalali-only
currency: IRR
displayUnit: toman-labelled-view
digitsUnderTest: Persian | Arabic | Latin
unicodeNormalization: NFC

Network فقط «وصل/قطع» نیست

DNS answer، Proxy، TLS trust، MTU، Latency، Packet loss، Retry، Connection pooling، IPv4/IPv6، Service discovery و Endpoint contract ممکن است فرق کنند. Reachableبودن یک Port رفتار Dependency را ثابت نمی‌کند. برای هر Dependency، Endpoint identity، Contract/version، Stub یا real-service بودن، Failure mode و Observation point را ثبت کنید.

Check سطحینتیجه‌ی محدودCheck رفتاری
TCP connect شدیک مسیر شبکه باز استRequest/response contract + timeout/retry
DNS resolve شدیک Answer دریافت شدAnswer set/TTL/route در دو Run
Health ۲۰۰ استHealth handler پاسخ دادهDependency readiness و مسیر واقعی سؤال
Service version برابر استLabel برابر گزارش شدهArtifact/Config/behavior Evidence

Running، Ready، Healthy و Correct را قاطی نکنید

Process Running می‌تواند هنوز Migration را اجرا نکرده، Dependency را پیدا نکرده یا Cache را گرم نکرده باشد. Readiness هم فقط شرط تعریف‌شده برای پذیرش Traffic است. Healthyبودن یک Probe و Correctبودن Business behavior Claims جدا هستند. Pipeline باید هر Claim را با Oracle و Evidence خودش ثبت کند.

Environment Parity هدف مطلق نیست

یکسان‌کردن کامل Development، Test و Production ممکن نیست و همیشه مطلوب هم نیست. Production ممکن است Scale، داده، Identity، Policy و Dependencyهایی داشته باشد که بازتولیدشان در لپ‌تاپ ناامن یا پرهزینه است. هدف، Fidelity کافی برای Claim حاضر و Deltaهای شناخته‌شده با Compensation است؛ نه کپی بی‌مرز Production.

Deltaممکن است پذیرفتنی باشد وقتی…Compensation نمونه
Scale کوچک‌ترسؤال Functionality محدود استPerformance evidence در بستر دیگر
Dependency StubContract و Failure mode کافی استContract test + محدودیت Claim
Synthetic dataInvariantهای سؤال حفظ شده‌اندData profile evidence
Architecture متفاوتBinary/behavior وابسته نیستTarget-arch smoke check

از Fingerprint به Environment Delta برسید

Delta خروجی Diff خام نیست. باید Field path، مقدار Source/Target یا Reference امن، طبقه‌بندی، ارتباط احتمالی با Question، Confidence، دلیل، Owner و آزمایش بعدی داشته باشد. نبودن Delta در Collector هم اثبات برابری نیست؛ ممکن است مدل Fingerprint ناقص باشد.

EnvironmentDelta {
  deltaId, comparisonId, algorithmVersion,
  leftFingerprintDigest, rightFingerprintDigest,
  dimension, path, sourceValueRef, targetValueRef,
  classification, relevance, rationale, confidence,
  ownerCapability, nextExperiment, state,
  supersedes, createdAt, digest
}

Taxonomy پیشنهادی Delta

کلاسمعنااقدام اولیه
ARTIFACT_MISMATCHبایت یا ورودی Build متفاوتFreeze و بازاجرای همان Artifact
PLATFORM_VARIANCEOS/Kernel/Arch/Runtime فرق داردCompatibility experiment
CONFIG_DRIFTSchema/key/flag فرق داردیک Flag/Key در هر بار
DATA_STATE_VARIANCESeed/Schema/Cache/Queue فرق داردReset و Snapshot کنترل‌شده
DEPENDENCY_VARIANCEEndpoint/Contract/behavior فرق داردStub/recorded response/control
TIME_LOCALE_VARIANCEClock/Timezone/Locale/Encoding فرق داردFreeze clock و canonical inputs
OBSERVABILITY_VARIANCEفقط دید ما فرق داردهم‌ترازکردن Instrumentation
UNKNOWN_UNCOLLECTEDمدل فعلی توضیح نمی‌دهدCollector را نسخه‌دار گسترش دهید

Reproduction Contract برای دو محیط

Reproduction باید Witness Run معیوب و Control Run غیرمعیوب را با Build، Artifact، Procedure و Oracle ثابت جفت کند. اگر چند متغیر را هم‌زمان تغییر دهید، نتیجه برای Isolation ضعیف می‌شود. Control هم تضمین Cause نیست؛ فقط Contrast می‌سازد.

EnvironmentReproduction {
  reproductionId, frozenBuildId, frozenArtifactDigest,
  sourceControlRun, targetWitnessRun,
  procedureVersion, preconditions, trigger,
  attemptIds, attemptCount, failureCount, controlCount,
  isolationOrder, oneVariableRule, resetProcedure,
  oracleId, evidenceManifestId, result,
  unknowns, limitations, digest
}

Witness Run و Control Run چگونه طراحی شوند؟

عنصرWitnessControl
Artifactهمان digest ثابتهمان digest ثابت
Triggerهمان Event/Request canonicalهمان Event/Request canonical
Oracleهمان versionهمان version
StateSnapshot شناخته‌شدهSnapshot هم‌ارز یا Delta ثبت‌شده
ObservationFailure قابل زمان‌بندیعدم Failure در Attempt مشخص
EvidenceManifest و TimelineManifest و Timeline هم‌ساختار

Isolation Order: از کم‌خطر و پرقدرت شروع کنید

  1. ابتدا Artifact identity و Procedure/Oracle را ثابت کنید.
  2. تفاوت Instrumentation را برطرف کنید تا دو Run قابل‌دیدن شوند.
  3. Config/Flag و Clock را با Change قابل‌بازگشت بررسی کنید.
  4. Data/Cache/Queue را با Snapshot و Reset آزمون کنید.
  5. Dependency response و Network conditions را کنترل کنید.
  6. Platform/Architecture را وقتی سؤال یا Evidence آن را محتمل می‌کند تغییر دهید.
  7. بعد از هر Intervention، Witness و Control تازه با Attempt ID بسازید.

این ترتیب Universal نیست؛ Risk و هزینه‌ی تغییر مهم‌اند. Secret، داده‌ی واقعی، Policy تولید یا سرویس بیرونی را برای سرعت آزمایش دور نزنید. اگر Intervention پرریسک است، به Environment امن‌تر یا Simulation منتقل شوید.

Minimal Reproduction و Delta Debugging

Minimal یعنی کوچک‌ترین مجموعه‌ی فعلاً شناخته‌شده برای حفظ Observation، نه «علت نهایی». هر بار یک Input، State یا Delta را حذف/جایگزین کنید و نتیجه را ثبت کنید. اگر Failure ناپدید شد، آن عامل Candidate می‌شود؛ Interaction، Order effect و Flakiness هنوز باید بررسی شوند.

ExperimentInterventionنتیجهبرداشت مجاز
E1فقط Timezone هم‌ترازFailure باقی ماندTimezone تنها توضیح کافی نیست
E2Timezone Reset، فقط Flag هم‌ترازFailure حذف شدFlag Candidate مرتبط است
E3Flag قبلی، مسیر Dedup مستقیمFailure بازگشترابطه تقویت شد، Cause کامل هنوز Claim نمی‌شود
E4Attemptهای تکراری با Seed تازه۴/۵ Failureنرخ و Unknown ثبت شود

Evidence Manifest؛ به‌جای انبوه Log

Evidence باید Subject و Run را پیدا کند، نه اینکه صرفاً حجم زیادی Attachment بسازد. Manifest بگوید هر شاهد برای کدام Build/Run/Environment/Delta است، چه زمانی و با کدام Collector گرفته شده، چه Redaction و Retention دارد و Digest آن چیست. Log کامل ممکن است Secret یا داده‌ی شخصی داشته باشد؛ کمینه‌سازی و دسترسی کنترل‌شده لازم است.

EvidenceManifest {
  manifestId, subjectId, buildId,
  sourceEnvironmentId, targetEnvironmentId,
  sourceRunId, targetRunId,
  fingerprintDigests[], deltaIds[],
  timelineRef, traceRef, metricRef, logExcerptRef,
  redactionPolicy, retention, access,
  collectedAt, digest
}

Timeline و Clock uncertainty

برابر بودن Timestamp متن Log ترتیب قطعی رخدادها را ثابت نمی‌کند. Clock drift، buffering، async export و timezone conversion می‌توانند Timeline را جابه‌جا نشان دهند. Event ID، parent/causal link، monotonic clock محلی، ingestion time و uncertainty را هرجا لازم است جدا کنید. Trace نیز ممکن است Sampling شده یا ناقص باشد.

Disposition: اختلاف را به چه تصمیمی ببریم؟

Dispositionمعناشرط خروج
PRODUCT_DEFECTرفتار محصول خلاف Basis در Context معتبرFix/verification جداگانه
ENVIRONMENT_DEFECTEnvironment Contract یا Readiness نقض شدهRepair + revalidation
TESTWARE_DEFECTTest/Oracle/Harness مشکل دارداصلاح versioned + rerun
EXPECTED_VARIANCEتفاوت مستند و پذیرفته‌شده استRationale + claim limit
NEEDS_INFOEvidence/Experiment کافی نیستMissing item + owner + due
DEFER_WITH_EXPIRYفعلاً اقدام نمی‌شودRisk owner + expiry + resume trigger

«Environment issue» مترادف «Not a bug» نیست. ممکن است Environment config خودش بخشی از Product delivery باشد. Authority تصمیم را از فردی که Evidence جمع کرده جدا و براساس Capability/Policy تعریف کنید.

Correction به‌جای پاک‌کردن نتیجه‌ی قبلی

اگر بعداً معلوم شد Source Run Artifact دیگری داشته یا Collector یک Field را اشتباه خوانده، Record قبلی را بی‌صدا ویرایش نکنید. Correction با شناسه‌ی تازه، رکورد Superseded، دلیل، Evidence تازه و Query تصمیم‌های متاثر بسازید. این الگو با Freshness و Drift مستندات تست هم‌راستا است.

CorrectionRecord {
  correctionId, supersededRecordId,
  reason, changedFields, newEvidenceRefs,
  affectedDecisionQuery, ownerCapability,
  publishedAt, acknowledgedBy,
  priorDigest, newDigest
}

آزمایشگاه فارسی: Callback تکراری در Checkout خیالی

این Lab کاملاً ساختگی و از هر شرکت، PSP، بانک، کاربر، پرداخت یا سامانه‌ی واقعی جداست. هیچ Network یا Production واقعی ندارد و توصیه‌ی بانکی، مالی، حقوقی، مالیاتی، امنیتی یا حریم خصوصی ایران نیست. Entityهای خیالی شامل Order، PaymentAttempt، PSP Stub، Callback Event، Ledger Entry و Reconciliation Job هستند.

شناسهControl (DEV-SYN-29)Witness (TEST-SYN-29)
Build/ArtifactBUILD-SYN-29 / sha256:synthetic29همان
Flag snapshotFLAGSET-SYN-۲۹-A؛ reconciliation onFLAGSET-SYN-۲۹-B؛ reconciliation off
TimezoneUTCAsia/Tehran
InputCallback تکراری EVT-SYN-۲۹همان canonical Event
Oracleیک Ledger effect برای Event IDهمان ORACLE-IDEMP-SYN-۲۹
Resultیک effectدو effect در Witness اولیه

داده فقط شناسه‌های ساختگی، IRR خیالی و نمای تومانِ صریحاً برچسب‌خورده دارد. ارقام فارسی/عربی/لاتین و Unicode NFC آزمایش می‌شوند؛ UTC منبع Instant است و Asia/Tehran/Jalali فقط View هستند. هیچ نام، موبایل، ایمیل، IP، حساب، PAN، CVV2، OTP، Cookie، Token، Credential، Log یا Screenshot واقعی استفاده نمی‌شود.

Fixture قابل‌تکرار: سبزی سطحی در برابر ۱۹۱ Finding

Fixture مستقل `SYN-ENVIRONMENT-DELTA-REPRO-۰۱` با Node.js و بدون Dependency بیرونی اجرا شد. داشبورد سطحی Commit `abc1234`، Tag `checkout:latest`، ۷۲/۷۲ Check توسعه و ۶/۶ Container در حال اجرا را دید و `PARITY_PASS` اعلام کرد. ممیزی ۱۹۲قاعده‌ای، ۱۵۸ Field الزامی، ۳۴ ادعای ممنوع و هشت رابطه را سنجید و همان ورودی را با دقیقاً ۱۹۱ Finding به HOLD برد.

گروهقاعدهنمونه
Identity16Build/Artifact/Run/Environment
Observation16Question/Actual/Impact/Unknown
Source + Target Fingerprint44Platform/Config/Time/Network/Data
Delta18Path/Relevance/Experiment/State
Reproduction20Witness/Control/Attempt/Reset/Oracle
Evidence18Manifest/Timeline/Trace/Access
Governance18Disposition/Authority/Correction/Limit
Forbidden + Relation42مطلق‌گویی و سازگاری بین Fieldها

نسخه‌ی اصلاح‌شده `BUILD-SYN-۲۹` و `sha256:synthetic29` را Freeze کرد، Fingerprintهای `FP-DEV-SYN-۲۹` و `FP-TEST-SYN-۲۹` را ساخت، Delta زمان/Flag را Candidate دانست، سه Attempt شامل دو Failure و یک Control را با حساب درست ثبت کرد و به `READY_FOR_ENVIRONMENT_DELTA_REVIEW` با صفر Finding رسید. این خروجی فقط کامل‌بودن ساختاری را نشان می‌دهد؛ نه Cause، درستی Evidence، نبود Defect، Parity، کیفیت محصول یا آمادگی Release.

Automation چه چیزی را جمع کند؟

  • Build/Artifact/Deployment identity و Provenance reference؛
  • Fingerprint با Schema و Collector version ثابت؛
  • Canonical diff با Ignore ruleهای بازبینی‌شده؛
  • Run/Attempt manifest، Exit semantics و Oracle version؛
  • Evidence index با Redaction، Retention و Access؛
  • Drift alert با Baseline دقیق، نه «محیط فرق کرد»؛
  • Correction link برای تصمیم‌ها و Resultهای متاثر.

در CI، Artifact، Cache، Report و Log را جدا نگه دارید؛ برای الگوی عملی، تست خودکار در GitLab CI را ببینید. یکپارچه‌سازی Collectorها نیز به Data Contract، Retry و Trace نیاز دارد؛ موضوعی که در یکپارچه‌سازی ابزارهای تست پوشش داده شده است.

AI در تحلیل Environment Delta

AI می‌تواند Deltaها را خوشه‌بندی، Fieldهای مشکوک را پیشنهاد، Log excerpt را Redact یا Experiment draft تولید کند. اما نباید Secret دریافت کند، Root cause را خودکار قطعی بداند، Evidence جعلی بسازد، Disposition یا Risk acceptance را بدون Authority صادر کند یا Record قبلی را بی‌ردپا بازنویسی کند. Prompt/model/version/input references و Human review را ثبت کنید.

معیارهای سالم و Countermetricها

MetricکاربردCountermetric
Time to first comparable pairسرعت ساخت Witness/ControlEvidence completeness
Unknown Delta ageپیری تفاوت‌های بی‌مالکDeltaهای اشتباه حذف‌شده
Reproduction attemptsهزینه و نرخ مشاهدهState reset quality
Fingerprint coverageابعاد جمع‌آوری‌شدهSensitive-data exposure
Correction latencyسرعت اصلاح ClaimAffected decisions reached
Environment-caused escapesیادگیری از طبقه‌بندیMisclassification/reopen rate

هدف «صفر Delta» یا «کمترین زمان بستن Ticket» نیست؛ این هدف‌ها Collector ناقص، پاک‌کردن تفاوت یا Disposition عجولانه را تشویق می‌کنند. کیفیت تصمیم و Claim limit را کنار سرعت بسنجید.

۳۴ Anti-pattern که باید متوقف شوند

  1. Commit یکسان یعنی Executable یکسان.
  2. Version label یا latest tag را هویت Artifact دانستن.
  3. Container را تضمین رفتار یکسان دانستن.
  4. Running، Ready، Healthy و Correct را یکی گرفتن.
  5. Pass توسعه را ابطال Failure هدف دانستن.
  6. Failure هدف را اثبات خرابی محیط دانستن.
  7. Environment issue را خودکار Not a defect بستن.
  8. Cannot reproduce را نبود Defect دانستن.
  9. یک Retry موفق را Closure دانستن.
  10. Copyکردن Secret برای Parity.
  11. Production parity را همیشه الزامی دانستن.
  12. Production data را شرط بازتولید دانستن.
  13. Log بیشتر را علت قطعی دانستن.
  14. Log کامل را Evidence امن فرض‌کردن.
  15. Timestamp برابر را ترتیب قطعی دانستن.
  16. Timezone را فقط نمایش دانستن.
  17. Locale را فقط ترجمه دانستن.
  18. Network را Up/Down مدل‌کردن.
  19. Version سرویس را هویت رفتار دانستن.
  20. Schema برابر را State برابر دانستن.
  21. Cache را بعد از Restart بی‌اثر دانستن.
  22. Feature Flag را جزئیات Deployment دانستن.
  23. Architecture را همیشه بی‌ربط دانستن.
  24. Package lock را اثبات بایت نصب‌شده دانستن.
  25. Fingerprint را اثبات Relevance علّی دانستن.
  26. حذف همه‌ی Deltaها بدون توجه به Claim.
  27. صفر Delta را تضمین رفتار یکسان دانستن.
  28. چند متغیر را در یک Experiment تغییر دادن.
  29. Reset بی‌مدرک بین Attemptها.
  30. Control Run بدون همان Oracle.
  31. تغییر بی‌صدای Report یا Fingerprint.
  32. AI برای Root cause یا Disposition خودکار.
  33. مالکیت مبهم «همه بررسی کنند».
  34. سرزنش فرد به‌جای مقایسه‌ی دو Run.

چک‌لیست ۳۲نقطه‌ای Owner

حوزهسؤال‌های کنترل
IdentityProtocol/Product/Repo/Commit/Build/Artifact/Release/Deployment مشخص است؟
RunsSource/Target Environment و Run/Attempt جدا هستند؟
ObservationExpected source، Actual، Trigger، Subject، Frequency، Unknown ثبت است؟
FingerprintSchema/Collector/time/digest و ابعاد لازم ثبت‌اند؟
ConfigSecret حذف و Reference/version نگه داشته شده است؟
DataSnapshot/Seed/Schema/Cache/Queue state شناخته شده است؟
DeltaPath/class/relevance/confidence/owner/next experiment دارد؟
ExperimentArtifact/Procedure/Oracle ثابت و یک متغیر تغییر می‌کند؟
AttemptsID، Reset، numerator/denominator و Timeline روشن است؟
EvidenceManifest/subject/run/digest/redaction/access/retention دارد؟
DecisionVocabulary، Authority، rationale، due/expiry/reopen روشن است؟
CorrectionSupersedes و Affected-decision query وجود دارد؟
Claimآنچه نتیجه ثابت نمی‌کند صریح نوشته شده است؟

Pilot سی‌روزه برای تیم کوچک

بازهکارخروجی/Guardrail
روز ۱–۵انتخاب یک Failure پرتکرار و تعریف Identity chainبدون دسترسی Production یا Secret
روز ۶–۱۰Fingerprint کمینه برای دو EnvironmentSchema v1 + redaction review
روز ۱۱–۱۵ساخت Witness/Control و Delta registryArtifact/Oracle ثابت
روز ۱۶–۲۰سه Experiment یک‌متغیرهAttempt IDs + reset evidence
روز ۲۱–۲۵Disposition و Correction drillAuthority/expiry/reopen
روز ۲۶–۳۰بازبینی Metric و تصمیم Scale/Adapt/StopCountermetric و claim limits

قالب نهایی Environment Delta Packet

Environment Delta Packet
1) Question + Expected Source + Observation + Unknowns
2) Repository/Commit/Build/Artifact/Release/Deployment IDs
3) Source and Target Environment/Run/Attempt IDs
4) Fingerprint schema/version/digests + redaction policy
5) Ranked Delta records + relevance/confidence/rationale
6) Frozen Reproduction + Witness/Control + Reset + Oracle
7) Evidence Manifest + Timeline/Trace/Metric/Excerpt refs
8) Experiment log: one change → observed result
9) Disposition + Authority + Owner + due/expiry/reopen
10) Claim limit + Correction/Affected-decision path

جمع‌بندی

«روی ماشین من کار می‌کند» را رد یا قبول نکنید؛ آن را به Source Run قابل‌ردیابی تبدیل کنید. سپس Target Witness را با همان Artifact، Procedure و Oracle جفت کنید، دو Fingerprint کمینه بسازید، Deltaها را بدون ادعای Cause رتبه‌بندی کنید و با Experimentهای یک‌متغیره پیش بروید. Docker، IaC و CI ابزارهای مفیدی برای کاهش بخشی از Drift هستند، اما قرارداد هویت، Runtime inputs، State، Evidence و Correction را جایگزین نمی‌کنند.

سؤالات متداول

آیا Docker مشکل «روی ماشین من کار می‌کند» را حل می‌کند؟

Docker می‌تواند بخشی از Artifact و Runtime filesystem را قابل‌حمل‌تر کند، اما Kernel/Architecture، Config، Secret reference، Clock، Network، Data، Dependency و Orchestration همچنان ممکن است فرق کنند. Image digest را ثابت و Deltaهای بیرون Image را جدا ثبت کنید.

بهترین راه مقایسه دو محیط چیست؟

دو Run مشخص را انتخاب کنید، Build/Artifact/Procedure/Oracle را ثابت کنید، Fingerprintهای هم‌Schema بگیرید، Delta Registry بسازید و هر Candidate را با یک Intervention قابل‌بازگشت آزمایش کنید. Diff خام Config به‌تنهایی کافی نیست.

اگر باگ فقط در محیط تست رخ دهد، Product Defect نیست؟

نمی‌توان از محل وقوع چنین نتیجه‌ای گرفت. Failure ممکن است Product، Environment، Testware، Data/State، Dependency یا Expected variance باشد؛ حتی Config محیط می‌تواند بخشی از محصول تحویلی باشد. Disposition به Basis و Evidence نیاز دارد.

چه اطلاعاتی را از Environment ثبت نکنیم؟

Secret، Token، Password، داده‌ی شخصی و Dump بی‌مرز Log/Environment variables را ثبت نکنید. با Policy و حداقل دسترسی، از Reference/version، Schema، presence و Digest امن استفاده کنید؛ Retention و Redaction را در Manifest بنویسید.

صفرشدن Environment Delta یعنی رفتار حتماً یکسان است؟

خیر. صفر Delta فقط می‌گوید Collector فعلی در Fieldهای مدل‌شده تفاوتی ندیده است. ورودی اندازه‌گیری‌نشده، State، Timing، Dependency یا نقص Collector ممکن است باقی بماند. Claim را به Schema، زمان و Runهای مقایسه‌شده محدود کنید.

دیدگاهتان را بنویسید