داشبورد می‌گوید Pass rate برابر ۱۰۰٪ و فقط پنج نقص ثبت شده است. Query بدون خطا اجرا شده، هیچ Field تهی نیست و نمودار سبز است. اما Pipeline فقط آخرین Retry را نگه داشته، Runهای متوقف‌شده را حذف کرده، سه Result دیررس هنوز نرسیده‌اند و Population این هفته با هفتهٔ قبل فرق دارد. داده از نظر Schema «تمیز» است؛ عدد برای تصمیم Release قابل‌اعتماد نیست.

ممیزی معیارهای تست نرم‌افزار فقط یافتن Null و Duplicate نیست. باید زنجیرهٔ کامل Question/Construct → Measurement/Instrument → Frame/Sample/Collection → Identity/Event/Data → Transform/Aggregation → Analysis/View → Claim/Decision را بررسی کند. هر لایه Error mode، Evidence و Owner مستقل دارد؛ خروجی نهایی نیز `FIT`، `FIT_WITH_LIMITS`، `NOT_FIT` یا `UNKNOWN` برای یک Use مشخص است، نه مهر جهانی «دادهٔ باکیفیت».

پاسخ کوتاه: Metric Integrity را چگونه ممیزی کنیم؟

  1. Consumer، Question، Decision، Action و هزینهٔ خطا را ثبت کنید.
  2. Construct و Metric Contract را پیش از Data profiling بررسی کنید.
  3. Population/Frame/Sample، Opportunity، Unit، Window و Denominator را ببندید.
  4. Instrument/Event/Identity و سیاست Retry، Missing، Late، Duplicate و Correction را ممیزی کنید.
  5. Lineage و Transform را با Golden، Seeded، Metamorphic و Reconciliation checks آزمایش کنید.
  6. فرض‌های تحلیل، وابستگی، uncertainty، Slice، multiplicity و Alternative explanation را آشکار کنید.
  7. View، Export و Claim را با همان Snapshot و Contract تطبیق دهید.
  8. Fitness را برای Use مشخص و با Limit/Expiry صادر کنید؛ Unknown را سبز نکنید.
  9. خطای کشف‌شده را با Supersession، Impact analysis، Replay و Notification اصلاح کنید.

Intent و کلیدواژه‌های این راهنما

جزءانتخاب
Intent اصلیاطلاعاتی/اجرایی؛ کشف خطا در جمع‌آوری، محاسبه و تفسیر معیارهای QA
کلمهٔ کلیدی اصلیممیزی معیارهای تست نرم‌افزار
کلیدواژه‌های فرعیخطاهای متریک تست، Test Metric Audit، Metric Integrity، کیفیت داده QA، تفسیر KPI تست
لانگ‌تیلچگونه صحت متریک تست را بررسی کنیم، تله‌های جمع‌آوری داده تست، خطای Pass Rate، ممیزی Dashboard QA، چک لیست کیفیت داده تست
پاسخ کوتاهدرستی عدد را از Fitness ادعا و تصمیم جدا کنید.

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

این صفحه مالک Metric Integrity Audit است: کشف و Disposition خطا از Construct تا Decision. برای تعریف سنجه از Metric Contract، برای انتخاب و حاکمیت KPI از KPI Governance، برای Signal سری زمانی از Metric Trend Review و برای مهاجرت Old/New از Measurement Migration استفاده کنید.

Chart Contract و Visual QA صحت نمایش را عمیق‌تر پوشش می‌دهد؛ Contribution Evaluation ادعای اثر QA را بررسی می‌کند؛ و Defect Density قرارداد تخصصی Defect/Size/Comparability دارد. این مقاله Audit عمومی زنجیرهٔ Measurement را می‌سازد، نه کاتالوگ Metric یا تحلیل علّی.

منابع و مرز استفاده از آن‌ها

  • Government Data Quality Framework کیفیت داده را Fit-for-purpose و وابسته به User need می‌داند و بر ارزیابی در کل Lifecycle و ارتباط شفاف Trade-offها تأکید می‌کند؛ آن را استاندارد اجباری QA یا قانون ایران معرفی نمی‌کنیم.
  • NIST/SEMATECH دربارهٔ Characterization فرایند اندازه‌گیری منابع Error، Bias، Variability و Uncertainty را برجسته می‌کند؛ این راهنمای Metrology را به‌عنوان Lens مهندسی اقتباس می‌کنیم، نه اینکه Software metric را اندازه‌گیری فیزیکی هم‌ارز یا NIST-compliant بنامیم.
  • راهنمای NIST برای Sampling plan Measurement/زمان/روش/اندازه/نقش را به سؤال هدف وصل می‌کند؛ روش Sample هر Metric باید متناسب با Population و Claim خودش باشد.
  • تعاریف استاندارد AAPOR Coverage، Measurement و Nonresponse error را در Survey برجسته می‌کند؛ آن را فقط برای Metricهای survey/feedback و فهم Total Survey Error به‌کار می‌بریم.
  • راهنمای اخلاقی ASA برای Statistical Practice طراحی Collection، Processing، Analysis، Interpretation و Presentation را یک مسئولیت پیوسته می‌داند؛ این منبع جای Statistician یا روش تخصصی را نمی‌گیرد.

Integrity یک ویژگی جهانی Dataset نیست

یک Dataset ممکن است برای شمارش Runهای امروز Fit باشد اما برای مقایسهٔ تیم‌ها، Trend فصلی یا Release gate Fit نباشد. Fitness باید به `use_id`، Consumer، Decision، Error tolerance، As-of و Expiry وصل شود. برچسب «Certified data» بدون Use boundary دام جدید است.

عدد درست، Metric معتبر و Claim درست سه چیزند

سطحپرسشنمونهٔ شکست
Computational correctnessفرمول روی Input داده‌شده درست اجرا شد؟تقسیم integer یا timezone اشتباه
Data integrityInput نماینده و مطابق Contract است؟Runهای Abort حذف شده‌اند
Construct validityMetric واقعاً Question/Construct را نمایندگی می‌کند؟Pass rate به‌عنوان «کیفیت»
Analytical validityروش و فرض‌ها با Data/Design سازگارند؟میانگین روی Distribution شدیداً چوله
Claim fitnessنتیجه فقط در Scope Evidence است؟Sample یک ماژول به کل محصول
Decision fitnessError/Unknown برای این Action قابل‌قبول است؟عدد Diagnostic برای Release gate

Metric Integrity Audit Loop

Use / Consumer / Question / Decision / Error cost
→ Construct + Metric + Claim contracts
→ Population / Frame / Sample / Opportunity
→ Instrument / Identity / Event / Collection
→ Raw snapshot + lineage + data-quality profile
→ Transform / aggregation / reconciliation tests
→ analysis design / assumptions / uncertainty / slices
→ View / export / narrative consistency
→ error register + severity / impact / disposition
→ FIT | FIT_WITH_LIMITS | NOT_FIT | UNKNOWN
→ decision receipt / monitoring / correction / re-audit

گام صفر: Use و هزینهٔ خطا را ثبت کنید

همان Error برای Exploration و Gate اثر یکسان ندارد. False green ممکن است Release پرریسک را عبور دهد؛ False red می‌تواند کار سالم را متوقف کند؛ False precision اعتماد کاذب می‌سازد؛ Delay تصمیم را بی‌مصرف می‌کند. پیش از Audit بنویسید کدام خطا مهم‌تر است و چه سطح Evidence لازم دارید.

use_id / consumer / question / decision / action
decision_due / scope / error_tolerance
false_positive_cost / false_negative_cost / delay_cost
required_freshness / required_coverage / required_uncertainty
authority / not_authorized_uses

لایهٔ ۱: Construct Error

اولین خطا قبل از Collection رخ می‌دهد: چیزی را اندازه می‌گیریم که Question نیست. تعداد Test، Defect یا Commit ممکن است Activity باشد، نه اثربخشی، کیفیت یا بهره‌وری. Construct را تعریف کنید، Non-example و Adjacent construct بدهید و Mechanism فرضی بین Metric و Concept را آشکار کنید.

Proxy Error و Goodhart risk

Proxy وقتی Target، Bonus یا Ranking می‌شود، رفتار Collection و System را عوض می‌کند. تست‌های کوچک‌تر، Defectهای خردشده، Retryهای پنهان یا Story split می‌توانند عدد را بهتر کنند بی‌آنکه Outcome بهتر شود. Audit باید `gaming_hypotheses`، Countermetric و Behavior observation داشته باشد؛ صرف گفتن «Goodhart» تشخیص کافی نیست.

لایهٔ ۲: Population و Frame Error

Target population آن چیزی است که Claim دربارهٔ آن است؛ Frame مجموعه‌ای است که واقعاً امکان مشاهده دارد. اگر فقط Runهای CI ثبت شوند، تست دستی/Exploratory خارج Frame است. اگر فقط تیکت‌های ثبت‌شده دیده شوند، کاربران خاموش و کانال‌های دیگر غایب‌اند. Coverage gap را با «داده نداریم» حفظ کنید، نه تعمیم خاموش.

Selection و Survivorship Bias

حذف Runهای Abort، Quarantine، Cancelled item، Customer churn یا سرویس Down، مجموعه‌ای از Survivorها می‌سازد. Pass rate فقط روی Runهای کامل‌شده می‌تواند دقیقاً هنگام بی‌ثباتی بهتر شود. Selection rule و Disposition همهٔ Unitهای Frame را Reconcile کنید.

Sample با Population یکی نیست

Facts دربارهٔ Sample خودکار Facts دربارهٔ Population نیستند. Sampling plan باید Frame، Scheme، Unit، Size، variability، precision، Slice و Nonresponse را متناسب با Claim ثبت کند. Logهای در دسترس معمولاً Probability sample نیستند؛ پس Confidence interval کلاسیک را بدون Design/assumptions معتبر به آن‌ها نچسبانید.

Feedback و Survey چهار خطای اضافه دارند

  • Coverage: چه کسانی اصلاً شانس دریافت Survey داشتند؟
  • Sampling: چه کسانی انتخاب شدند و با چه احتمال/روش؟
  • Measurement: wording، scale، order و channel چه اثری داشت؟
  • Nonresponse: پاسخ‌دهندگان با غایبان در Construct موردنظر چه تفاوتی دارند؟

Response rate پایین به‌تنهایی مقدار Bias را نمی‌دهد و Response rate بالا آن را صفر نمی‌کند؛ Disposition و تفاوت مرتبط پاسخ‌دهندگان/غایبان مهم است. NPS یا رضایت را بدون Frame و Question wording قابل‌مقایسه ندانید.

Opportunity و Denominator Error

پنج Escape در ده Release با پنج Escape در ده‌هزار Session یک Claim نیست. Denominator باید Opportunity-to-observe را نمایندگی کند: Release، exposed user/session، transaction، requirement، risk یا size. تغییر Opportunity mix و zero denominator Policy را ثبت کنید. عدد بدون مخرج ممکن است فقط Volume باشد.

لایهٔ ۳: Measurement Instrument Error

Instrument در QA می‌تواند Runner، Reporter، Tracker workflow، Survey، Query یا Rubric انسانی باشد. Instrument ممکن است Resolution ناکافی، Drift، نسخهٔ متفاوت، Observer effect، misclassification یا blind spot داشته باشد. «خودکار است» به معنای Accurate، Complete یا unbiased نیست.

Repeatability و Reproducibility را متناسب تعریف کنید

برای Metric نرم‌افزاری بپرسید: همان Snapshot+Contract+Code دو بار همان خروجی می‌دهد؟ محیط/نسخهٔ Engine یا Reviewer دیگر چه Deltaی دارد؟ این اصطلاحات را دقیقاً معادل Metrology فیزیکی نمی‌گیریم؛ هدف یافتن variation در Measurement system است. Determinism خروجی، Construct validity را ثابت نمی‌کند.

Classification Error و Taxonomy Drift

Severity، Root cause، Escape boundary و Result status توسط انسان/Rule طبقه‌بندی می‌شوند. Ambiguous label، Incentive، training و تغییر Taxonomy distribution را جابه‌جا می‌کند. Codebook، version، examples/non-examples، calibration sample، disagreement و `UNKNOWN` لازم است.

Observer و Self-report Error

Time sheet، Effort، Confidence، Satisfaction و Cause ممکن است Recall، social-desirability یا incentive bias داشته باشند. Self-report را با رفتار/Artifact/independent evidence Triangulate کنید؛ اختلاف را «دروغ» ننامید. Privacy و اثر نظارت بر رفتار نیز جزئی از Integrity است.

لایهٔ ۴: Identity و Event Error

Test case، Execution، Attempt، Result، Defect، Work item، Build، Release و Deployment هویت‌های متفاوت‌اند. Join اشتباه Grain را منفجر می‌کند: یک Defect متصل به سه Attempt ممکن است سه Defect شمرده شود. Primary key، relationship cardinality و snapshot identity را ممیزی کنید.

Retry و Attempt Policy

First attempt، last attempt، any-pass، final accepted Result و all attempts پاسخ‌های متفاوت‌اند. نگه‌داشتن فقط آخرین Pass، Flake و Failure demand را پنهان می‌کند؛ شمردن همهٔ Retryها به‌عنوان Testهای مستقل مخرج را متورم می‌کند. Raw attempts را حفظ و View را با Policy نسخه‌دار بسازید.

Duplicate، Late و Out-of-order Event

At-least-once delivery Duplicate می‌سازد؛ Queue delay Result را پس از Dashboard snapshot می‌رساند؛ clock skew ترتیب را عوض می‌کند. `event_id`، event_time، ingested_at، idempotency key، watermark، lateness window و correction/replay Policy لازم‌اند. Received-late را silently drop نکنید.

Timestamp و Timezone Error

Created، Started، Finished، Ingested، Corrected و Viewed زمان‌های جدا هستند. UTC instant را canonical نگه دارید و Zone/version را برای View ثبت کنید. بریدن Window با تاریخ محلی، تبدیل دوگانه یا مخلوط epoch second/millisecond می‌تواند Result را جابه‌جا کند. تاریخ جلالی Presentation است، نه Event authority.

Missingness یک State است، نه صفر

Missing ممکن است Not collected، Not arrived، Not applicable، redacted، failed instrumentation یا unknown باشد. تبدیل همه به صفر/Pass یا حذف row، Bias می‌سازد. Reason code، rate by Slice، dependency on outcome و imputation policy را ثبت کنید. Imputed value باید Flag شود و Claim محدود بماند.

Censoring و Truncation

در Snapshot امروز، Itemهای تمام‌نشده Cycle time نهایی ندارند؛ حذفشان فقط Completedهای سریع را نشان می‌دهد. Timeout capped، log retention و max-duration نیز Tail را قطع می‌کنند. Work Item Age، survival-aware analysis یا حداقل اعلام Censoring لازم است؛ روش به Question بستگی دارد.

Schema و Unit Drift

Field همان نام را دارد اما meaning، enum، unit، precision یا nullability عوض شده است. Millisecond/second، IRR/toman یا Critical/Blocker می‌تواند Series را بشکند. Schema contract فقط type نیست؛ semantic version، effective time، compatibility و consumer acknowledgment می‌خواهد.

لایهٔ ۵: Collection و Data Quality Error

Accuracy، Completeness، Uniqueness، Consistency، Timeliness و Validity Lensهای مفیدی‌اند، اما اولویتشان به Use وابسته است. Report روزانه شاید Timeliness را با Completeness trade کند؛ Gate ایمنی شاید نتواند. Rule هر Dimension، Target، owner، observation و Action باید صریح باشد.

dq_rule_id / field_or_relation / dimension / use_ref
predicate / population / window / threshold / rationale
observed / unknown / sample_or_full / owner
action / exception / expiry / correction

Freshness با Event recency یکی نیست

آخرین Event تازه ممکن است وسط یک Backlog قدیمی باشد. Freshness شامل source watermark، ingestion lag، processing lag، snapshot time و completeness-as-of است. Dashboard باید `as_of` و data-health state داشته باشد. stale یا partial را سبز نشان ندهید.

Validity Rule با Business Truth فرق دارد

`severity ∈ enum` فقط Schema validity را می‌سنجد؛ درست‌بودن Severity برای Defect را نه. `duration ≥ ۰` Time semantics را ثابت نمی‌کند. هر Rule باید دقیقاً بگوید چه Failure class را کشف می‌کند و چه چیزی را Claim نمی‌کند.

لایهٔ ۶: Transform و Aggregation Error

Filter، Join، Dedup، Window، Group، Weight، Rounding، currency/time conversion و default value می‌توانند عدد را عوض کنند. Transform باید Code/version/digest، input snapshot، parameters و output snapshot داشته باشد. Query review بدون Fixture کافی نیست.

Join Explosion و Grain Mismatch

قبل از Join، Grain هر Table و cardinality مورد انتظار را بنویسید. Row count، distinct identity، unmatched left/right و multiplicity distribution را قبل/بعد Reconcile کنید. `DISTINCT` برای پنهان‌کردن Explosion ممکن است دادهٔ واقعی را نیز حذف کند.

Aggregation و Simpson’s paradox

Aggregate ممکن است بهتر شود درحالی‌که هر Slice بدتر شده، چون Mix تغییر کرده است. Module، Risk، Channel، Locale، Device، Test type یا Release cohort را از پیش بر اساس Question بررسی کنید. Slice mining پس از نتیجه بدون correction/label، Cherry-picking می‌شود.

Average Tail را پنهان می‌کند

Mean با Outlier/Tail حساس است؛ Median Tail را نشان نمی‌دهد؛ Percentile با Sample کوچک، interpolation و aggregation method تغییر می‌کند. Distribution، count، missing/censored و relevant quantiles را کنار Summary ببینید. Percentileهای گروه‌ها را بدون Raw data/وزن درست Average نکنید.

Ratio و Rate دو Error surface دارند

Numerator و Denominator هر دو Contract و Error دارند؛ covariance نیز ممکن است مهم باشد. Pass rate با حذف Failure و افزودن Retry همزمان بهتر می‌شود. Ratio بدون raw counts، exposure و uncertainty می‌تواند نوسان Sample کوچک را بزرگ نشان دهد.

Rounding و Display Precision

دو تیم با ۹۴.۵۱ و ۹۵.۴۹ هر دو ۹۵% نمایش داده می‌شوند؛ Threshold روی مقدار Roundشده می‌تواند تصمیم را عوض کند. محاسبه را با precision canonical انجام، rounding mode را ثبت و Display precision را متناسب با uncertainty انتخاب کنید. Decimal بیشتر Accuracy بیشتر نیست.

Golden، Seeded و Metamorphic Test

نوع کنترلهدفمثال
GoldenExpected output مستقل برای Input ثابت۶ Attempt → Numerator/Denominator معلوم
Seeded defectاثبات حساسیت Audit به Failure معلومDuplicate، late، wrong timezone
Metamorphicرابطهٔ لازم بدون Oracle کاملReorder input نباید نتیجه را عوض کند
Reconciliationحفظ count/amount/identity بین مراحلInput=accepted+rejected+unknown
Shadowمقایسهٔ Pipeline/Version بدون اثر تصمیمOld/New delta taxonomy
Backtestرفتار روی Snapshot تاریخی مجازKnown correction دوباره کشف شود

لایهٔ ۷: Analysis Error

Analysis باید Design، سؤال و نوع Data را بشناسد. Independence، distribution، stationarity، exposure، missing mechanism و multiplicity را فرض نکنید. روش پیچیده روی Data نامعتبر Integrity نمی‌سازد؛ روش ساده هم اگر Claim محدود و Design مناسب باشد می‌تواند کافی باشد.

Uncertainty را با یک CI تزئینی حل نکنید

Uncertainty می‌تواند از Sampling، Measurement، Classification، Missingness، Transform، Model و temporal variation بیاید. یک Confidence interval معمولاً فقط بخشی از آن را تحت فرض‌های مشخص پوشش می‌دهد. Error/uncertainty budget بنویسید و اجزای غیرقابل‌کمی‌سازی را کیفی نگه دارید.

error_component / layer / mechanism / direction
affected_population / evidence / estimated_magnitude_or_unknown
decision_sensitivity / detectability / owner
control / residual_risk / status / expiry

Small n و Rare event

صفر Incident در Window کوتاه اثبات ایمنی نیست؛ یک Escape در دو Release نرخ ناپایداری می‌سازد. Raw count/exposure، interval مناسب، prior evidence و طول Observation را گزارش کنید. Threshold ثابت روی rate کوچک می‌تواند Alert تصادفی بسازد.

Autocorrelation و Pseudoreplication

صد Attempt یک Test روی یک Build، صد Observation مستقل نیست. Eventهای متوالی، Sprintها و Retryها وابسته‌اند. Treat کردن آن‌ها به‌عنوان n مستقل uncertainty را کوچک می‌کند. Unit of analysis و cluster/time structure را ثبت کنید.

Seasonality، Mix shift و Regression to mean

پس از یک هفتهٔ بسیار بد، بازگشت عدد به محدودهٔ معمول ممکن است بدون Intervention رخ دهد. تعطیلات، Release type، campaign و traffic mix نیز Trend را عوض می‌کنند. قبل/بعد دو نقطه‌ای را Improvement ننامید؛ Context annotation و Comparison مناسب لازم است.

Correlation، Causation و Confounding

Coverage بالا و Escape پایین می‌توانند هر دو پیامد Module ساده‌تر، تیم باتجربه‌تر یا Release کوچک‌تر باشند. Correlation فقط association در Data/Design مشخص است. RCA نیز به‌تنهایی causal effect یک Intervention را تخمین نمی‌زند. Claim را محدود و Alternative explanation را ثبت کنید.

Multiple looks و Cherry-picking

اگر ده‌ها Metric/Slice/Window را تا یافتن نتیجهٔ مطلوب امتحان کنید، False signal بالا می‌رود. Analysis plan، primary/secondary/exploratory label، stopping rule و treatment مناسب multiplicity لازم است. نتیجهٔ exploratory می‌تواند Hypothesis بسازد، نه اثبات قطعی.

Statistical significance با Decision importance فرق دارد

اثر کوچک با n بزرگ ممکن است statistically detectable اما بی‌اهمیت باشد؛ اثر مهم با Data کم ممکن است uncertainty بالا داشته باشد. Effect size، interval، practical threshold، harm/cost و decision consequence را کنار هر نتیجه گزارش کنید. p-value Measure کیفیت Data یا احتمال درست‌بودن Hypothesis نیست.

Outlier را خاموش حذف نکنید

Outlier می‌تواند Error، Incident واقعی یا Slice مهم باشد. Rule حذف را پیش از نتیجه، با دلیل و Sensitivity analysis نسخه‌دار کنید. Report با/بدون نقطه و Disposition آن را حفظ کنید. Winsorize یا cap کردن Tail باید آشکار باشد.

لایهٔ ۸: View و Narrative Error

Chart می‌تواند Data درست را گمراه‌کننده نشان دهد: Axis، scale، color، bin، sorting، missing marker، denominator و comparison period. Table/Export/API ممکن است Snapshot دیگری داشته باشد. Visual QA، accessible table و checksum/snapshot reference لازم‌اند.

Label leakage و Semantic compression

کارت «Quality ۹۵%» چند قرارداد را در یک Label بی‌معنا فشرده می‌کند. Label باید Metric name/version، population/window/unit و state را قابل‌دسترسی کند؛ Tooltip جای Contract نیست. نام «Defect escape» با Definition متفاوت در دو Dashboard باید Conflict ایجاد کند.

Claim از Data بزرگ‌تر نشود

claim_id / revision / metric_snapshot_refs
question / population / window / slices
result / uncertainty / limitations / counterevidence
interpretation / alternative_explanations
decision_supported / actions_not_supported
owner / reviewer / expires / correction_link

Metric Error Register

finding_id / audit_id / layer / rule / observation
metric_snapshot / affected_rows_population_windows
severity / confidence / direction / magnitude_or_unknown
affected_views_claims_decisions / evidence
owner / disposition / due / correction / closure

Severity را از اثر بالقوه بر Decision بگیرید، نه تعداد Row. Confidence دربارهٔ Finding را از Impact جدا کنید. Dispositionهای پیشنهادی: `CONFIRMED_ERROR`، `EXPECTED_LIMITATION`، `ACCEPTED_FOR_USE`، `NOT_APPLICABLE`، `DUPLICATE`، `NEEDS_EVIDENCE` و `REJECTED_WITH_RATIONALE`.

Fitness Gate چهارحالته

خروجیمعناAction
FITبرای Use مقید، Finding باز فراتر از tolerance نیستاستفاده تا Expiry و Monitoring
FIT_WITH_LIMITSUse ممکن است اما Limit/Unknown باید همراه Claim باشدAction محدود و Follow-up
NOT_FITError/Gap می‌تواند تصمیم را نامعتبر کندBlock/replace/correct
UNKNOWNEvidence Audit کافی نیستسبز/Pass ممنوع؛ Evidence جدید

Audit Pass کیفیت محصول را ثابت نمی‌کند

`FIT` یعنی Measurement/Claim برای Use مقید طبق Ruleهای نسخه‌دار به اندازهٔ لازم سالم است. این خروجی Product quality، Release safety، Coverage adequacy، KPI suitability، Cause، Improvement یا decision correctness را اثبات نمی‌کند. Evidence سالم می‌تواند Risk بد را صادقانه نشان دهد.

ممیزی Risk-based و Sampling Audit

ممیزی همهٔ Metric×Window×Slice×Consumer همیشه ممکن نیست. Critical use، automated action، recent change، poor data health، high gaming incentive و wide exposure را اولویت دهید. Sampling Audit فقط دربارهٔ Sample بررسی‌شده Claim دارد؛ برای Population کامل Evidence یا طراحی استنباط لازم است.

استقلال Reviewer متناسب با ریسک

Author Pipeline می‌تواند Self-check کند؛ Use پرریسک ممکن است Reviewer مستقل از Producer/Target owner بخواهد. استقلال مطلق همیشه عملی نیست؛ Conflict، Reviewer competence و Challenge record را ثبت کنید. Approval مدیریتی جای بازتولید عدد نیست.

Metric برای رتبه‌بندی افراد نیست

Defect count، Test count، Cycle time، Coverage، Velocity و Pass rate Context سیستم را حمل می‌کنند. استفاده برای Bonus/Ranking رفتار Collection را تغییر می‌دهد و Audit را بی‌اعتبار می‌کند. `people_scoring=false`، unit of analysis، purpose/use limitation و دسترسی نقش‌محور را ثبت کنید.

Privacy، Minimization و Re-identification

Join ریزدانهٔ Git/Test/Issue/Chat می‌تواند افراد را حتی پس از حذف نام بازشناسایی کند. فقط Field لازم برای Question را بگیرید؛ Aggregation، pseudonymization، access, retention/deletion، export/audit و ممنوعیت secondary use را تعیین کنید. Audit integrity مجوز surveillance نیست.

Correction وقتی Metric قبلاً مصرف شده است

correction_id / discovered_at / owner / cause_layer
affected_metric_revisions / snapshots / windows / slices
affected_views_exports_claims_alerts_decisions
old_result / corrected_result / uncertainty
replay_or_restated / original_preserved / supersedes
consumer_notification / remediation / revalidation / closure

Correction فقط Fix Query نیست. Impact analysis باید بگوید چه Dashboard، Report، Alert، Claim و Decisionی متاثر بوده است. Original را حفظ، Corrected را supersede و Consumer را آگاه کنید. اگر Raw data برای Restatement کافی نیست، نتیجه را `UNRESOLVED` نگه دارید.

آزمایش اجرایی: ۱۰۰٪ Pass و پنج نقص

Fixture زیر کاملاً ساختگی و آفلاین است. Checker سطحی عددهای non-null و وضعیت `METRIC_TRUSTED` را می‌بیند. ممیزی Integrity دارای ۶۵ Rule است؛ ۶۴ جزء غایب‌اند و Rule آخر People scoring را منع می‌کند. چون false است، نسخهٔ خام دقیقاً ۶۴ Finding می‌گیرد. Rule count Benchmark یا سطح بلوغ نیست.

const draft = {
  metrics: { pass_rate: 100, defects: 5 },
  declared_status: "METRIC_TRUSTED",
  people_scoring: false
};

const present = (v) =>
  v !== undefined && v !== null &&
  !(typeof v === "string" && v.trim() === "") &&
  !(Array.isArray(v) && v.length === 0);

const rules = [
  ["MI-01 audit_id", x => present(x.audit_id)],
  ["MI-02 revision", x => present(x.revision)],
  ["MI-03 supersedes", x => present(x.supersedes)],
  ["MI-04 as_of", x => present(x.as_of)],
  ["MI-05 use_id", x => present(x.use_id)],
  ["MI-06 consumer", x => present(x.consumer)],
  ["MI-07 question", x => present(x.question)],
  ["MI-08 decision", x => present(x.decision)],
  ["MI-09 action", x => present(x.action)],
  ["MI-10 error_tolerance", x => present(x.error_tolerance)],
  ["MI-11 construct", x => present(x.construct)],
  ["MI-12 construct_boundaries", x => present(x.construct_boundaries)],
  ["MI-13 metric_contract", x => present(x.metric_contract)],
  ["MI-14 claim_contract", x => present(x.claim_contract)],
  ["MI-15 target_population", x => present(x.target_population)],
  ["MI-16 frame", x => present(x.frame)],
  ["MI-17 coverage_gap", x => present(x.coverage_gap)],
  ["MI-18 sample_plan", x => present(x.sample_plan)],
  ["MI-19 unit_grain", x => present(x.unit_grain)],
  ["MI-20 opportunity", x => present(x.opportunity)],
  ["MI-21 denominator", x => present(x.denominator)],
  ["MI-22 instrument", x => present(x.instrument)],
  ["MI-23 instrument_version", x => present(x.instrument_version)],
  ["MI-24 instrument_checks", x => present(x.instrument_checks)],
  ["MI-25 taxonomy_codebook", x => present(x.taxonomy_codebook)],
  ["MI-26 identity_contract", x => present(x.identity_contract)],
  ["MI-27 event_contract", x => present(x.event_contract)],
  ["MI-28 attempt_policy", x => present(x.attempt_policy)],
  ["MI-29 duplicate_policy", x => present(x.duplicate_policy)],
  ["MI-30 late_order_policy", x => present(x.late_order_policy)],
  ["MI-31 time_contract", x => present(x.time_contract)],
  ["MI-32 missing_policy", x => present(x.missing_policy)],
  ["MI-33 censoring_policy", x => present(x.censoring_policy)],
  ["MI-34 schema_unit_contract", x => present(x.schema_unit_contract)],
  ["MI-35 raw_snapshot", x => present(x.raw_snapshot)],
  ["MI-36 lineage", x => present(x.lineage)],
  ["MI-37 data_quality_rules", x => present(x.data_quality_rules)],
  ["MI-38 freshness_as_of", x => present(x.freshness_as_of)],
  ["MI-39 transform_version", x => present(x.transform_version)],
  ["MI-40 join_cardinality", x => present(x.join_cardinality)],
  ["MI-41 aggregation_policy", x => present(x.aggregation_policy)],
  ["MI-42 rounding_policy", x => present(x.rounding_policy)],
  ["MI-43 golden_tests", x => present(x.golden_tests)],
  ["MI-44 seeded_tests", x => present(x.seeded_tests)],
  ["MI-45 metamorphic_tests", x => present(x.metamorphic_tests)],
  ["MI-46 reconciliation", x => present(x.reconciliation)],
  ["MI-47 analysis_plan", x => present(x.analysis_plan)],
  ["MI-48 assumptions", x => present(x.assumptions)],
  ["MI-49 uncertainty", x => present(x.uncertainty)],
  ["MI-50 slices", x => present(x.slices)],
  ["MI-51 multiplicity", x => present(x.multiplicity)],
  ["MI-52 alternative_explanations", x => present(x.alternative_explanations)],
  ["MI-53 outlier_policy", x => present(x.outlier_policy)],
  ["MI-54 view_export_checks", x => present(x.view_export_checks)],
  ["MI-55 error_register", x => present(x.error_register)],
  ["MI-56 fitness_rules", x => present(x.fitness_rules)],
  ["MI-57 fitness_output", x => present(x.fitness_output)],
  ["MI-58 limitations", x => present(x.limitations)],
  ["MI-59 not_claimed", x => present(x.not_claimed)],
  ["MI-60 owners_reviewers", x => present(x.owners_reviewers)],
  ["MI-61 privacy_access", x => present(x.privacy_access)],
  ["MI-62 monitoring", x => present(x.monitoring)],
  ["MI-63 expiry", x => present(x.expiry)],
  ["MI-64 correction_policy", x => present(x.correction_policy)],
  ["MI-65 people_scoring_prohibited", x => x.people_scoring !== true]
];

const findings = (x) => rules.filter(([, ok]) => !ok(x)).map(([id]) => id);
console.log("SUPERFICIAL", Object.keys(draft.metrics).length, draft.declared_status);
console.log("INTEGRITY", findings(draft).length ? "HOLD" : "FIT", findings(draft).length);

const corrected = {
  audit_id: "SYN-MI-042", revision: "v1", supersedes: "none:first-revision",
  as_of: "2026-08-13T11:00:00Z", use_id: "USE-SYN-RELEASE-BRIEF",
  consumer: "ROLE-SYN-DECISION", question: "what bounded evidence is complete and interpretable?",
  decision: "investigate, gather evidence or proceed to separate risk review", action: "no automatic release gate",
  error_tolerance: "zero silent exclusions; declared residual uncertainty",
  construct: "accepted decision evidence", construct_boundaries: ["not product quality", "not tester productivity"],
  metric_contract: "METRIC-SYN-042-v1", claim_contract: "CLAIM-SYN-042-v1",
  target_population: "fictional checkout evidence attempts", frame: "all synthetic manifest IDs",
  coverage_gap: "none in frozen pack; production excluded", sample_plan: "full frozen synthetic pack; no population inference",
  unit_grain: "one immutable Attempt", opportunity: "manifested accepted-or-rejected evidence attempt",
  denominator: "all eligible manifest Attempts including aborted/unknown",
  instrument: "offline synthetic collector", instrument_version: "COLLECTOR-SYN-v1",
  instrument_checks: ["same snapshot deterministic", "seeded missing/duplicate/late detected"],
  taxonomy_codebook: "CODEBOOK-SYN-v1 with unknown and calibration",
  identity_contract: "Test/Execution/Attempt/Result/Defect/Build IDs distinct",
  event_contract: "event_id/entity/event_time/ingested/schema/correction",
  attempt_policy: "all Attempts retained; accepted-result view separate", duplicate_policy: "idempotency plus duplicate finding",
  late_order_policy: "watermark/replay/correction; never silent drop", time_contract: "UTC instant; Tehran display only",
  missing_policy: "reason-coded unknown; never zero/pass", censoring_policy: "unfinished retained and separately analyzed",
  schema_unit_contract: "versioned enums/units/null semantics", raw_snapshot: "RAW-SYN-MI-042-digest",
  lineage: "source-to-transform-to-view-to-claim graph", data_quality_rules: "DQ-SYN-MI-v1 fit for use",
  freshness_as_of: "source/ingestion/processing/snapshot timestamps", transform_version: "TRANSFORM-SYN-v1-digest",
  join_cardinality: "declared 1:n with pre/post reconciliation", aggregation_policy: "counts and slices before rates",
  rounding_policy: "full precision decision; labelled display rounding",
  golden_tests: "known numerator/denominator/output", seeded_tests: ["abort", "retry", "duplicate", "late", "timezone", "missing"],
  metamorphic_tests: ["input reorder invariant", "duplicate ID cannot raise accepted count"],
  reconciliation: "manifest=accepted+rejected+unknown with identity lists",
  analysis_plan: "predeclared descriptive audit; no causal or population inference",
  assumptions: ["frozen synthetic data", "full manifest frame"], uncertainty: "structural unknowns reported; no decorative CI",
  slices: ["timeout-before", "timeout-after", "retry"], multiplicity: "primary checks fixed; extras exploratory",
  alternative_explanations: ["instrument failure", "mix shift", "semantic drift"],
  outlier_policy: "retain; investigate; sensitivity report", view_export_checks: "same snapshot/contract/checksum plus accessible table",
  error_register: "REGISTER-SYN-MI-042-v1", fitness_rules: "RULESET-SYN-MI-v1 by use and severity",
  fitness_output: "READY_FOR_METRIC_INTEGRITY_REVIEW", limitations: ["synthetic", "bounded", "no real users or production"],
  not_claimed: ["product quality", "release safety", "KPI fitness", "causality", "improvement"],
  owners_reviewers: ["metric owner", "data steward", "consumer", "independent bounded reviewer"],
  privacy_access: "synthetic only; least privilege; expiry; no identity", monitoring: "data health and contract drift alerts",
  expiry: "2026-10-01T11:00:00Z", correction_policy: "supersede; impact/replay/notify; preserve original",
  people_scoring: false
};

const correctedFindings = findings(corrected);
console.log("CORRECTED", correctedFindings.length ? "HOLD" : "READY_FOR_METRIC_INTEGRITY_REVIEW", correctedFindings.length);

خروجی مستقل Fixture و مرز تفسیر

SUPERFICIAL 2 METRIC_TRUSTED
INTEGRITY HOLD 64
CORRECTED READY_FOR_METRIC_INTEGRITY_REVIEW 0

دو عدد non-null هیچ Integrityای اثبات نمی‌کنند؛ Rule منع People scoring تنها Rule پاس‌شده است. نسخهٔ اصلاح‌شده صفر Finding ساختاری دارد، اما صدق Raw evidence، اعتبار Construct/Instrument، کفایت Error rules، نبود Bias، Fitness واقعی Metric، کیفیت محصول، Release safety، Cause یا Decision correctness را ثابت نمی‌کند. خروجی عمداً Review است، نه Trusted/Approved.

آزمایشگاه آفلاین فارسی برای Metric Integrity

یک Checkout کاملاً ساختگی و بدون شبکه بسازید: fake Order، PaymentAttempt، PSP Stub، Callback، Ledger، Reconciliation و Notification. Manifest مستقل Attemptها را Authority قرار دهید. سپس timeout پیش/پس از fake commit، retry any-pass، duplicate callback، late Result، reordered Event، Abort، missing Result، reopen و schema drift را Seed کنید.

SeedChecker سطحیIntegrity Audit
آخرین Retry فقط PassPass rate بهترAttempt loss و any-pass policy finding
Abort حذف‌شدهDenominator کوچک‌ترSelection/survivorship finding
Callback duplicateDefect/Event بیشترIdentity/reconciliation finding
Late ResultSnapshot سبزFreshness/Correction finding
IRR به تومان بی‌برچسبعدد معتبرUnit/semantic drift finding
Tehran time دوباره تبدیل‌شدهDuration عددیTime-contract/transform finding
Missing=PassSchema کاملUnknown-policy violation

مرزهای ایران، داده و حریم خصوصی Lab

Tenant/Order/Attempt/Event/Ledger/Test/Execution/Result/Defect/Run/Build/Snapshot/Metric/Claim/Decision شناسه‌های جدا و ساختگی دارند. مبلغ فقط IRR خیالی و تومان با برچسب «نمایشی» است. ارقام فارسی/عربی/لاتین، ی/ی، ک/ک، ZWNJ، RTL/Bidi، UTC instant، Asia/Tehran view و تاریخ جلالی صرفاً نمایشی آزموده می‌شوند.

Lab هیچ اتصال شبکه، Production، سازمان/تیم/کاربر/سفارش/پرداخت/PSP/بانک واقعی، پول واقعی، دادهٔ HR، PII، نام، موبایل، ایمیل، IP، حساب، PAN، CVV2، OTP، Cookie، Token، Credential، Log یا Screenshot واقعی ندارد و توصیهٔ بانکی، مالی، حقوقی، مالیاتی، امنیتی، آماری، منابع انسانی یا حریم خصوصی نیست.

Pilot سی‌روزهٔ Metric Integrity Audit

  1. روز ۱ تا ۵: یک Use پرتصمیم، Consumer، Question، Error cost و Contracts را انتخاب کنید.
  2. روز ۶ تا ۱۰: Population/Frame/Instrument/Identity/Event/Lineage را Baseline کنید.
  3. روز ۱۱ تا ۱۵: DQ rules و Golden/Seeded/Metamorphic/Reconciliation pack بسازید.
  4. روز ۱۶ تا ۲۰: Transform/View/Export را روی Frozen snapshots بازتولید کنید.
  5. روز ۲۱ تا ۲۴: Analysis assumptions، uncertainty، Slice و Alternativeها را Review کنید.
  6. روز ۲۵ تا ۲۷: Error register و Impact بر Claims/Decisions را Triage کنید.
  7. روز ۲۸ تا ۳۰: Fitness محدود، Follow-up، Monitoring، Expiry و Correction rehearsal را ثبت کنید.

ضدالگوهای جمع‌آوری و تفسیر Metric

  • شروع Audit از Chart به‌جای Question/Use؛
  • برابر دانستن Query success با Metric truth؛
  • برابر دانستن non-null با Data quality؛
  • Proxy activity به‌عنوان Quality/Productivity؛
  • Target/Bonus روی Metric بازی‌پذیر؛
  • Frame ناقص و Claim کل Population؛
  • Sample راحت بدون Limit؛
  • Survey بدون Coverage/Nonresponse analysis؛
  • Volume بدون Opportunity/Denominator؛
  • ابزار خودکار به‌عنوان Instrument بی‌خطا؛
  • Taxonomy بدون Version/Unknown/Calibration؛
  • Join Test/Attempt/Defect با Grain مبهم؛
  • نگهداری فقط آخرین Retry؛
  • Drop کردن Duplicate/Late بدون Evidence؛
  • Missing=۰، Missing=Pass یا row deletion؛
  • حذف unfinished item از Duration؛
  • Schema type ثابت با Semantic/Unit drift؛
  • Fresh timestamp به‌عنوان Complete snapshot؛
  • `DISTINCT` برای پوشاندن Join explosion؛
  • Aggregate بدون Slice/Mix؛
  • Mean یا Percentile بدون Distribution/count؛
  • Rate بدون raw numerator/denominator؛
  • Decimal زیاد به‌عنوان Accuracy؛
  • CI بدون Sampling/independence assumptions؛
  • Retryها به‌عنوان Observation مستقل؛
  • دو نقطه قبل/بعد به‌عنوان Improvement؛
  • Correlation یا RCA به‌عنوان Causality؛
  • جست‌وجوی Slice/Window تا نتیجهٔ مطلوب؛
  • p-value به‌عنوان Importance/Truth؛
  • حذف Outlier بعد از دیدن نتیجه؛
  • Chart/Export روی Snapshot متفاوت؛
  • Claim بزرگ‌تر از Population/Window Evidence؛
  • Pass Audit به‌عنوان Product quality؛
  • Metric برای Ranking/Bonus افراد؛
  • اصلاح Query بدون Impact/Notification.

چک‌لیست Auditor پیش از Fitness decision

  • Use/Consumer/Question/Decision/Action و Error cost مشخص‌اند؟
  • Construct/Metric/Claim contracts نسخه‌دارند؟
  • Population/Frame/Coverage/Sample/Opportunity روشن‌اند؟
  • Unit/Grain/Denominator/Window/Attempt policy بسته‌اند؟
  • Instrument/version/check/Taxonomy calibration ثبت است؟
  • Identity/Event/Time/Schema/Unit contracts وجود دارند؟
  • Missing/Duplicate/Late/Order/Censoring policy صریح است؟
  • Raw snapshot و lineage بازتولیدپذیرند؟
  • DQ rules به Use و Action متصل‌اند؟
  • Freshness/Completeness/Unknown در View آشکار است؟
  • Transform/Join/Aggregation/Rounding نسخه‌دارند؟
  • Golden/Seeded/Metamorphic/Reconciliation checks پاس شده‌اند؟
  • Analysis plan و Assumptionها قبل از Claim ثبت‌اند؟
  • Uncertainty components و Limitهای غیرکمی آشکارند؟
  • Slice/Mix/Small-n/dependence/multiplicity بررسی شده‌اند؟
  • Alternative explanation و Outlier policy وجود دارد؟
  • View/Table/Export/API همان Snapshot/Contract را دارند؟
  • Error register، Impact و Disposition کامل است؟
  • Fitness فقط برای Use/Expiry مشخص صادر می‌شود؟
  • `people_scoring=false`، Privacy، Not claimed و Correction صریح‌اند؟

پرسش‌های متداول درباره ممیزی معیارهای تست

چگونه بفهمیم یک متریک تست قابل‌اعتماد است؟

«قابل‌اعتماد» را به Use محدود کنید. Construct و Contract، Population/Frame، Instrument، Identity/Event، Data quality، Transform، assumptions، uncertainty، View و Claim را ممیزی کنید. سپس فقط برای Decision مشخص `FIT` یا `FIT_WITH_LIMITS` صادر کنید؛ Metric هیچ اعتبار جهانی ندارد.

آیا خودکارسازی جمع‌آوری داده خطا را حذف می‌کند؟

خیر. Automation خطای ثبت دستی را کم می‌کند، اما Instrument blind spot، Retry policy، Event loss/duplicate، Schema drift، Join/Transform error و Bias طراحی را خودکار و تکرارپذیر می‌کند. Collector و Pipeline به Contract، Fixture، Reconciliation و Monitoring نیاز دارند.

آیا Defect Escape از Pass Rate بهتر است؟

هیچ‌کدام ذاتاً بهتر نیستند. Pass rate به Population/Attempt/Oracle/Result policy وابسته است؛ Escape به Defect/Detection boundary/Exposure/Window/Reporting. Metric را با Question و Decision انتخاب و محدودیتش را ممیزی کنید. جایگزینی Vanity metric با Proxy دیگری Integrity نمی‌سازد.

اگر داده ناقص است، آیا می‌توان Missing را صفر گذاشت؟

فقط اگر Contract و معنای Domain واقعاً ثابت کند Missing=zero؛ این حالت معمولاً باید از ابتدا به‌صورت Rule روشن باشد. در غیر این صورت reason-coded `UNKNOWN` نگه دارید، Missingness را بر اساس Slice بررسی و هر Imputation را Flag و با Sensitivity/Limit گزارش کنید.

ممیزی Metric را هر چند وقت یک‌بار انجام دهیم؟

Cadence جهانی ندارد. Criticality تصمیم، سرعت تغییر Source/Schema/Workflow، Data-health history، Gaming incentive و هزینهٔ Audit را در نظر بگیرید. تغییر Contract، Instrument، Taxonomy، Population، Transform، Consumer یا Threshold باید Re-audit رویدادمحور ایجاد کند.

جمع‌بندی: عدد را تا تصمیم دنبال کنید

Metric Integrity با پاک‌کردن Null تمام نمی‌شود. Question و Construct، Population/Frame/Sample، Instrument، Identity/Event، Missing/Late/Duplicate/Censoring، Schema/Unit، Lineage/Transform، Analysis/Uncertainty، View و Claim همه بخشی از Measurement system هستند. Error هر لایه می‌تواند عددی دقیق اما تصمیمی غلط بسازد.

Golden و Seeded fixture، Metamorphic check، Reconciliation و Error register را کنار Data profiling قرار دهید. Fitness را برای Use مشخص، با Limit و Expiry صادر کنید؛ Unknown را سبز نکنید و Pass Audit را کیفیت محصول ننامید. اگر خطا بعداً کشف شد، Original و تصمیم‌های متاثر را حفظ، نتیجه را supersede و Consumer را مطلع کنید. هدف زیباترکردن عدد نیست؛ قابل‌دیدن‌کردن مرز آن است.

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