ماژول A چهار نقص و ۲ KLOC دارد؛ چگالی نقص آن ۲ است. ماژول B شش نقص و ۶ KLOC دارد؛ چگالیاش ۱ است. داشبورد فوراً A را «دو برابر بدتر» معرفی میکند و برای Refactor اولویت میدهد. اما A طی ۳۰ روز با تستهای عمیق بررسی شده، B فقط هفت روز در دسترس بوده، تعریف نقص آنها متفاوت است و ابزار شمارش Lines of Code نیز یکسان نیست. کسرها درستاند؛ مقایسه نادرست است.
چگالی نقص نرمافزار (Software Defect Density) فقط وقتی قابلتفسیر است که هم صورتِ کسر—نقصهای یکتا، تأییدشده و واجدشرایط—و هم مخرج—Size یا Exposure نسخهدار—در یک Window، Cutoff و Population مشخص قرارداد داشته باشند. این معیار تعداد نقصهای مشاهدهشده به ازای واحد اندازه را میسنجد؛ نه نقصهای پنهان، نه کیفیت کلی محصول، نه عملکرد فرد و نه علت مشکل.
پاسخ کوتاه: فرمول عمومی
Observed eligible unique defects ÷ eligible sizeاست. ولی عدد بدون Defect Contract، Size Contract، Observation Window، Data-quality Gate و Comparability Gate فاقد معنای تصمیمی است. Density پایین میتواند از کیفیت بهتر، کشف ضعیفتر، Window کوتاهتر یا مخرج بزرگتر بیاید.
این راهنما چه چیزی را مالک میشود؟
این صفحه مالک قرارداد اندازهگیری و قابلیتمقایسهٔ Defect Density است: Information need → Numerator/Denominator contract → Observation/Maturity → Snapshot/Data quality → Computation → Comparability Gate → bounded interpretation → Investigation/Action → Correction. برای کاتالوگ عمومی معیارها به متریکهای تست نرمافزار و برای چرخهٔ Triage/State/SLA به مدیریت نقص نرمافزار مراجعه کنید.
این راهنما Benchmark صنعت، مدل پیشبینی نقص، کنترل آماری روند یا تصمیم انتشار ارائه نمیکند. آن مسائل بهترتیب نیازمند پروتکل مقایسهٔ همسان، مدل پیشبینی ریسک نقص، تحلیل Noise و Signal معیارها و چارچوب تصمیم مستقلاند.
تعریف عملی چگالی نقص
Observed Defect Density = count(unique eligible observed defects) ─────────────────────────────────────── eligible size or explicitly named exposure Example unit: confirmed unique defects / KESLOC KESLOC = 1,000 eligible executable source lines under one counting rule
واژهٔ Observed حیاتی است. Defect latent که هنوز کشف نشده، در Numerator حاضر نیست. بنابراین «صفر Defect مشاهدهشده» برابر «صفر Defect موجود» نیست. همچنین Density یک Rate مشاهده است؛ تبدیل آن به «درصد کیفیت» یا «احتمال سالمبودن» بدون مدل و شواهد جداگانه مجاز نیست.
چگالی نقص چه چیزی را ثابت نمیکند؟
- کیفیت کلی، قابلیت اطمینان یا امنیت محصول را ثابت نمیکند.
- تعداد نقصهای پنهان یا Residual defect content را مستقیماً اندازه نمیگیرد.
- علت نقص، ضعف طراحی، کمبود Coverage یا عملکرد یک تیم را ثابت نمیکند.
- موفقیت TDD، Refactoring، Automation یا Process change را اثبات نمیکند.
- بهتنهایی Hotspot پرریسک، Release gate یا اولویت کسبوکار تعیین نمیکند.
- عدد کمتر را بدون پروتکل همسان «بهتر» و عدد بیشتر را «بدتر» نمیکند.
چرا Defect Density مترادف Quality نیست؟
ISO/IEC 25010:2023 مدل کیفیت محصول را با ۹ مشخصه و زیرمشخصههای مرتبط تعریف میکند. صفحهٔ عمومی ISO جزئیات کامل استاندارد را رایگان عرضه نمیکند، اما همین دامنه روشن میکند کیفیت یک عدد تکبعدی نیست. Defect Density ممکن است دربارهٔ یک مشاهدهٔ محدود اطلاعات بدهد؛ Usability، Performance efficiency، Security، Compatibility یا Context of use را خودکار پوشش نمیدهد.
حتی نسبتدادن Density فقط به Reliability نیز سادهسازی است: Defect با Failure یکی نیست، همهٔ Defectها در Operation فعال نمیشوند و فرصت مشاهده بین محصولات فرق دارد. بهتر است Claim چنین باشد: «در Scope و Window مشخص، X نقص یکتای واجدشرایط به ازای Y واحد Size مشاهده شد.»
Defect، Failure، Incident، Issue و Change Request را جدا کنید
| موجودیت | تعریف عملی محدود | ورود به Numerator |
|---|---|---|
| Defect | ناهمخوانی تأییدشدهٔ Work product با Basis نسخهدار | فقط طبق Eligibility contract |
| Failure | رفتار مشاهدهشدهٔ سیستم که از نتیجهٔ مورد انتظار منحرف شده | نه، مگر به Defect یکتا و واجدشرایط نگاشت شود |
| Incident | رویداد عملیاتی نیازمند پاسخ | خودکار نه؛ میتواند چند Defect یا هیچ Defect نرمافزاری داشته باشد |
| Issue | مانع، پرسش یا مشکل عمومی Workflow | خیر، مگر Classification آن Defect شود |
| Change request | درخواست تغییر رفتار یا Scope | خیر، مگر مبنای قبلی نقض شده باشد |
| Duplicate report | گزارش دوم از همان Defect identity | یک Defect، نه دو مورد |
اول Information Need، بعد فرمول
ISO/IEC/IEEE 15939:2017 فرایند اندازهگیری را به نیاز اطلاعاتی، تعریف/انتخاب Measure، کاربرد نتایج تحلیل و بررسی اعتبار آنها متصل میکند. ما از صفحهٔ عمومی ISO فقط همین جهتگیری سطحبالا را میگیریم؛ این مقاله مدعی دسترسی به متن کامل یا انطباق با استاندارد نیست.
| سؤال ضعیف | Information need قابلاجرا |
|---|---|
| کدام تیم باگ بیشتری دارد؟ | در کدام Componentهای همنوع و همفرصت، Evidence بیشتری برای Investigation برنامهریزی تست لازم است؟ |
| کیفیت ما چند است؟ | نرخ نقصهای یکتای تأییدشدهٔ پس از انتشار برای Cohort ثابت طی Window بالغ چقدر بوده؟ |
| آیا TDD موفق شد؟ | آیا تغییر Process طبق طراحی Evaluation و Counterfactual مناسب به Outcome مرتبط بوده؟ |
| آیا عدد زیر ۱ است؟ | آیا Density تحت Contract و Baseline همسان از Trigger ازپیشتعریفشده عبور کرده؟ |
قرارداد کامل Defect Density
density_review_id: DD-SYN-042-v1 information_need: "select comparable components for deeper investigation" decision_ref: DEC-SYN-042 metric_id: M-OBS-DEFECT-DENSITY-v3 subject_population: POP-SYN-CHECKOUT-COMPONENTS-v2 artifact_snapshot: ART-SYN-b42-C42 numerator: defect_definition: DEF-CONTRACT-v4 eligible_states: [CONFIRMED, RESOLVED, CLOSED] identity_rule: canonical_defect_id duplicate_rule: one canonical defect phase: system-test sources: [manual-session, deterministic-suite] discovery_window: 2026-07-01T00:00:00Z/2026-07-31T23:59:59Z denominator: method: KESLOC-RULE-v2 unit: 1000 eligible executable source lines exclusions: [blank, comment-only, generated, vendored] measured_at: artifact freeze cutoff: 2026-08-15T00:00:00Z maturity_rule: 14d after observation-window close data_snapshot: SNAP-SYN-DD-042 comparability_profile: CMP-DD-v2 not_claimed: [latent-defects, total-quality, cause, people-performance, release] owner_role: ROLE-METRIC-STEWARD review_due: 2026-10-01T09:00:00Z correction_policy: supersede; no silent edit
Numerator Contract: کدام نقصها شمرده میشوند؟
«Total defects» تعریف نیست. Numerator باید Defect type، Artifact/Basis، State، Source، Phase، Severity vocabulary، Discovery window، Attribution rule، Duplicate/Reopen و Exclusion داشته باشد. Internal review finding، Test-environment issue، Production incident و Customer report را بیقاعده در یک سبد نریزید.
| فیلد | نمونهٔ قرارداد | اگر حذف شود |
|---|---|---|
| Defect definition | نقض قابلبازتولید نسبت به Basis v7 | Issue و Change request وارد شمارش میشوند |
| Eligible state | CONFIRMED/RESOLVED/CLOSED | گزارش ردشده یا Needs-info شمرده میشود |
| Identity | Canonical defect ID | Duplicateها Density را بالا میبرند |
| Source | System test و field-confirmed جدا | فرصت کشف نامتجانس میشود |
| Window | Event time و Cutoff مشخص | مقایسهٔ ۷ روز با ۳۰ روز رخ میدهد |
| Attribution | Component affected در Artifact snapshot | نقص مشترک چندبار یا به مالک نادرست نسبت داده میشود |
Defect identity و Deduplication
یک Failure میتواند چند Report بسازد و یک Defect میتواند چند Failure pattern داشته باشد. Canonical defect ID، رابطهٔ duplicates، affected versions و evidence refs را نگه دارید. Dedup فقط شباهت عنوان نیست؛ Domain owner باید بداند آیا Root condition و Fix واحد است. ادغام اشتباه نیز میتواند Defectهای مستقل را پنهان کند.
State، Reopen و Rejected چه اثری دارند؟
یک Defect بین OPEN، CONFIRMED، RESOLVED، CLOSED و REOPENED حرکت میکند. Density بر اساس Snapshot state محاسبه شود، نه شمارش Eventهای تغییر State. Reopen همان Canonical ID است مگر Evidence نشان دهد Defect مستقل است. REJECTED/NOT_A_DEFECT و DUPLICATE معمولاً از Numerator خارجاند، ولی شمارشان بهعنوان Data/Process countermetric مفید است.
Discovery phase و Source را مخلوط نکنید
Review defect، Unit-test defect، System-test defect و Post-release defect فرصت کشف و معنای متفاوت دارند. افزایش Early defects ممکن است از Detection بهتر بیاید؛ افزایش Field defects Exposure دیگری دارد. Densityها را Stratify کنید یا نام دقیق بدهید: System-test observed defect density و Post-release observed defect density، نه یک Total مبهم.
Injected، Detected، Escaped و Residual را یکی نگیرید
| نوع Claim | آنچه واقعاً میدانیم | محدودیت |
|---|---|---|
| Detected density | نقصهای مشاهدهشده در Phase/Window | به Detection opportunity وابسته است |
| Escape density | نقصهای منتسب به Phase قبلی و کشفشده بعدتر | Attribution و maturity دشوار است |
| Injected density | نقصهای منتسب به زمان/فعالیت ورود | Root/Origin evidence لازم دارد |
| Residual density | برآورد نقصهای باقیمانده | مشاهدهٔ مستقیم نیست و مدل جدا میخواهد |
| Failure density | Failureهای مشاهدهشده بر Exposure | Defect count نیست |
زمانهای Defect را تفکیک کنید
| زمان | کاربرد | اشتباه رایج |
|---|---|---|
| introduced_at/version | فرضیهٔ Origin | حدس آن از تاریخ Report |
| observed_at | وقوع Failure/Observation | جایگزینی با ایجاد Ticket |
| reported_at | ورود به Tracker | نادیدهگرفتن Reporting lag |
| confirmed_at | تأیید Eligibility | شمارش پیش از Triage |
| resolved_at | ثبت Fix candidate | برابرگرفتن با Closure |
| closed_at | Closure طبق Evidence | تغییر Attribution window |
| snapshot/cutoff | وضعیت قابلبازتولید گزارش | محاسبهٔ امروز روی Query شناور |
Observation Window، Cutoff و Maturity
Window میگوید کدام Observationها واجدشرایطاند؛ Cutoff میگوید داده تا چه لحظهای وارد Snapshot شده؛ Maturity مشخص میکند چه مدت برای Report/Confirmation دیررس صبر کردهایم. Release تازه نمیتواند با Release ششماهه مقایسه شود. Caseهای نارس باید PROVISIONAL/CENSORED بمانند، نه صفر.
Data Specification نرمافزار SEI یک نمونهٔ دقیق از Post-release defect density را با نقصهای یکتا، واحد Size و Window ششماهه ارائه میکند. این Window نسخهٔ همان Specification است، نه قانون عمومی برای همهٔ تیمها. درس قابلانتقال، ثبت صریح unique/window/size است.
Severity را وزن دلخواه ندهید؛ Stratify کنید
فرمولهایی مانند Critical×۱۰ + Major×۵ + Minor×۱ وزنها را به واقعیت علمی تبدیل نمیکنند. Severity، Priority، Exposure و Business consequence جدا هستند. ابتدا Density را بر Severity vocabulary نسخهدار Stratify کنید و Count خام هر طبقه را نگه دارید. اگر Utility weighting لازم است، Authority، rationale، sensitivity analysis و نام Measure تازه ثبت شود.
Denominator Contract: «اندازه» دقیقاً چیست؟
مخرج تزئین نیست؛ Population of opportunity را تقریبی میکند. KLOC، Logical statements و Function points قابلتعویض نیستند. Size باید روی Artifact snapshot همان Scope، با Tool/version/rule ثابت و در زمان مشخص محاسبه شود. اگر Numerator مربوط به Checkout است، مخرج کل Monorepo نتیجه را رقیق میکند.
KLOC بدون Counting Rule قابلبازتولید نیست
راهنمای SEI برای شمارش Source statements بر تعریف، ثبت و گزارش روشهای Size تأکید دارد. «۱۰ هزار خط» باید روشن کند Physical یا Logical، فایلهای واجدشرایط، زبانها، Comment/blank، multi-statement line، preprocessor و Tool version چه هستند.
size_contract: KESLOC-RULE-v2 artifact_ref: repo://synthetic-checkout@C42 included_languages: [typescript] included_paths: [src/checkout/**] excluded_paths: [vendor/**, generated/**, test-fixtures/**, build/**] blank_lines: exclude comment_only_lines: exclude mixed_code_comment: count as executable per tool rule generated_code: exclude and report separately vendored_code: exclude and report separately reused_internal_code: include only if owned in subject scope tool: SYN-LOC-COUNTER-v2 measured_at: 2026-07-01T00:00:00Z unit: KESLOC
Generated، Vendored و Reused code را آشکار کنید
Generated code میتواند مخرج را بزرگ و Density را مصنوعی کم کند؛ Vendored dependency معمولاً تحت کنترل مستقیم تیم نیست؛ Reused internal code ممکن است مالکیت مشترک داشته باشد. Include/Exclude به سؤال تصمیم بستگی دارد، اما هر انتخاب باید جداگانه گزارش شود. تغییر Generator یا Vendor بدون Defect change، Trend را میشکند.
چند زبان و چند Repository چه مشکلی میسازند؟
یک Line در SQL، TypeScript، YAML و یک زبان Generated فرصت/معنای مشابه ندارد. جمع KLOC زبانهای ناهمگون فقط با Claim محدود و Composition ثابت قابلاستفاده است. Composition را کنار Density نگه دارید؛ برای مقایسهٔ جدی، زبان/Artifact type را Segment یا یک Size method معنادارتر انتخاب کنید.
Function Point جایگزین جادویی KLOC نیست
Function Point میتواند اندازهٔ کارکرد را مستقلتر از Syntax بسنجد، اما روش شمارش، Boundary، Counter qualification و Snapshot خودش را میخواهد. Defects/FP را با Defects/KLOC در یک Trend وصل نکنید. Migration به Denominator تازه باید Series جدید یا Bridge study نسخهدار بسازد.
Exposure-based rate را Defect Density کد ننامید
برای Operation، مخرج Transaction، active-user hour، request یا device-day گاهی به سؤال نزدیکتر است؛ اما آن Measure ممکن است Incident rate یا Failure rate باشد، نه Code defect density. نام، واحد و Numerator را صریح عوض کنید. یک Defect میتواند هزار Failure بسازد و هزار Failure ممکن است از یک Defect مشترک بیاید.
Size صفر، کوچک یا منفی چه میشود؟
Size صفر Division error است و باید INVALID/HOLD شود. مخرج بسیار کوچک Rate ناپایدار میسازد؛ یک Defect جهش بزرگی ایجاد میکند. «Size منفی» در Density Snapshot معنا ندارد؛ اگر Net code change منفی است، آن Measure دیگری است. Minimum denominator و نمایش Count خام را از قبل تعیین کنید.
واحد و Scale را در هر Claim بنویسید
0.002 defects/LOC و 2 defects/KLOC یک مقدارند، اما حذف Scale خطای هزاربرابری میسازد. Defects/۱۰۰ FP با Defects/FP فرق دارد. واحد Canonical، Display unit، Precision و Round rule را ثبت کنید؛ مقدار خام را برای Recompute نگه دارید.
Data Snapshot و Lineage
snapshot_id: SNAP-SYN-DD-042 extract_at: 2026-08-15T01:00:00Z event_cutoff: 2026-08-15T00:00:00Z defect_source_version: TRACKER-SCHEMA-v5 size_source_version: LOC-RULE-v2 query_digest: sha256:fictional-demo-only eligible_defects: 10 duplicates_excluded: 3 rejected_excluded: 2 late_provisional: 1 missing_component: 1 join_failures: 0 fitness_state: PASS supersedes: none:first-snapshot limitations: synthetic, offline, non-representative
Density باید از دو Lineage به همپیوسته بیاید: Defect registry و Size snapshot. اگر Component mapping ناقص باشد، Numerator به مخرج اشتباه Join میشود. Missing را صفر نکنید؛ Duplicate و Rejected را بدون Audit trail حذف نکنید؛ Late data را با Correction وارد کنید.
Data-quality Gate پیش از محاسبه
| کنترل | PASS نمونه | در شکست |
|---|---|---|
| Schema/version | Defect و Size contract شناختهشده | HOLD و migrate |
| Identity | Canonical ID یکتا | Quarantine/Dedup review |
| Join | هر Defect به Subject مجاز نگاشت شده | UNKNOWN، نه تخصیص حدسی |
| Window/maturity | Observation همسان و بالغ | PROVISIONAL |
| Denominator | مثبت و بالاتر از Minimum | INVALID/HOLD |
| Freshness | هر دو Source داخل SLA | STALE |
| Completeness | Missing زیر حد ثبتشده | HOLD یا bounded limitation |
Detection opportunity متغیر پنهان اصلی است
تیمی که تست عمیقتر، کاربران بیشتر یا Telemetry بهتر دارد احتمالاً نقص بیشتری مشاهده میکند. Density بالا میتواند Detection system قویتر را بازتاب دهد؛ Density پایین میتواند از کمبود فرصت کشف بیاید. Test effort، Risk coverage، Environment، Traffic/exposure، channels و reporting friction را Context نگه دارید.
فرصت کشف را به یک عدد Coverage تقلیل ندهید
Code coverage، تعداد Case یا ساعت تست بهتنهایی Detection opportunity نیست. Risk areas، Oracle strength، Data diversity، Environment fidelity، Session depth، user exposure و telemetry health نیز اثر دارند. این Contextها Adjustment خودکار نیستند؛ ابتدا Comparability را میسنجند و در صورت نیاز تحلیل را Segment میکنند.
Comparability Gate: آیا اصلاً حق تقسیم و مقایسه داریم؟
COMPARABLE only if all required dimensions match or have an approved bridge: information_need subject/artifact type and ownership boundary defect definition, state, identity, duplicate/reopen rules discovery phase, source and observation opportunity profile observation window, cutoff and maturity denominator method, tool/version, scope and unit data-quality/freshness thresholds severity vocabulary and stratification attribution and join rules relevant context/segment composition Else: NOT_COMPARABLE or COMPARABLE_WITH_LIMITATIONS Never force a ranking.
ماتریس قابلیتمقایسه
| بعد | A | B | نتیجه |
|---|---|---|---|
| Defect contract | Confirmed only v4 | Open+Confirmed v2 | Mismatch |
| Window/maturity | ۳۰ روز + ۱۴ روز بلوغ | ۷ روز، نارس | Mismatch |
| Size | KESLOC، generated خارج | Physical LOC، generated داخل | Mismatch |
| Detection opportunity | System+exploratory | Smoke only | Mismatch |
| Data health | PASS | Missing component map | HOLD |
| Density | ۲ | ۱ | محاسبهپذیر اما غیرقابلمقایسه |
Benchmark داخلی بهتر از عدد جادویی است
Baseline داخلی فقط وقتی مفید است که Contract و Context پایدار باشند. Cohortهای همنوع را مقایسه کنید، Median/range و Count خام را نگه دارید و Known changes را Annotate کنید. Baseline توصیف گذشته است؛ Target، Control limit یا حد پذیرش نیست. بازتنظیم مداوم آن برای سبزشدن ممنوع است.
چرا Benchmark صنعت معمولاً قابلانتقال نیست؟
بازهٔ «۰٫۵ تا ۲ Defect/KLOC قابلقبول است» بدون منبع، Domain، Phase، Severity، Window، Size rule، Language، Detection opportunity و maturity معنای عمومی ندارد. حتی عدد منتشرشدهٔ معتبر فقط به همان Dataset/Protocol مربوط است. برای مقایسهٔ بیرونی، Data dictionary و Sampling/Counting protocol دو طرف باید همسان یا Bridge معتبر داشته باشد.
مقایسهٔ Componentها چه زمانی مجاز است؟
Componentها باید Boundary، Artifact type، lifecycle phase، Size rule، Observation opportunity، Window و Defect classification مشابه داشته باشند. Shared defect را طبق Attribution rule یا یک Subject مشترک حساب کنید؛ آن را در همهٔ Componentها Duplicate نکنید. Component کوچک را فقط بر Density رتبهبندی نکنید.
Simpson’s paradox و تغییر ترکیب
Density کل ممکن است کاهش یابد چون سهم Component بزرگ و کمDensity بیشتر شده، در حالی که هر Component جداگانه بدتر شده است. زبان، Risk class، new/reused code، Phase و Severity را Segment کنید و هم Aggregate هم Strata را نشان دهید. Composition drift را بهجای داستان «بهبود» ثبت کنید.
مخرج کوچک و Rate ناپایدار
یک نقص در ۰٫۲ KLOC برابر ۵/KLOC میشود، ولی این عدد Precision بالایی ندارد. Count خام، denominator، interval یا uncertainty مناسب و Minimum-size policy را نمایش دهید. Small module را میتوان برای Review انتخاب کرد، اما Rank قطعی «بدترین کیفیت» از Rate ناپایدار نسازید.
صفر Defect چه معنایی دارد؟
صفر فقط میگوید در Window و Sources تعریفشده، Defect واجدشرایط ثبت نشده است. اگر Detection opportunity یا maturity کم باشد، Evidence ضعیف است. Dashboard باید 0 observed، Size، Window، exposure و limitation را نشان دهد؛ «بدون باگ»، «۱۰۰٪ کیفیت» یا «Ready» ننویسد.
Count/rate data به فرض آماری نیاز دارد
NIST در بحث Control chart برای Countها «واحد بازرسی» و فرصت وقوع Defect را پیش از مدل Poisson تعریف میکند. این مثال صنعتی، روش آماده برای Software نیست. Defectهای نرمافزاری ممکن است مستقل یا با Rate ثابت نباشند؛ خوشهبندی، تغییر Exposure و Detection process فرضهای ساده را میشکنند.
قبل از Interval، Test یا Control chart، واحد، استقلال/خوشهبندی، Overdispersion، zero inflation و varying exposure را بررسی کنید. فرد دارای صلاحیت آماری باید روش را با داده و تصمیم تطبیق دهد. فرمول خودکار Poisson بهتنهایی اعتبار نمیسازد.
Trend نزولی مساوی Improvement نیست
Density نزولی میتواند از Defect کمتر، Size بیشتر، تست کمتر، Window کوتاه، تغییر Classification یا تاخیر Report بیاید. Contract/Data gate را Freeze، numerator و denominator را جدا رسم و تغییرها را Annotate کنید. تشخیص Noise/Signal و Rebaseline باید در پروتکل تحلیل روند معیارهای تست انجام شود؛ Signal نیز Cause نیست.
Target، Benchmark و Control Limit را یکی نکنید
| مفهوم | معنا | استفادهٔ ممنوع |
|---|---|---|
| Baseline | رفتار تاریخی تحت Contract ثابت | هدف مطلوب |
| Benchmark | مرجع مقایسه با Protocol تعریفشده | عدد عمومی صنعت |
| Target | سطح مطلوب/تعهد تصمیمی | حد آماری رفتار |
| Control limit | مرز محاسباتی رفتار فرایند تحت فرضها | قبولی محصول |
| Threshold | Trigger ازپیشتعریفشدهٔ Action | اثبات Cause یا Quality |
Density بالا فقط Trigger تحقیق است
اگر Comparability و Data quality پاساند، Density بالا میتواند Component را برای Review Evidence انتخاب کند. هنوز معلوم نیست Complexity، Requirement، Test depth، Ownership boundary یا Classification علت بوده است. Investigation باید Observation، hypotheses، alternatives، evidence plan، owner و due داشته باشد.
Defect Density با Risk score فرق دارد
Risk به سناریو، asset/journey، likelihood evidence، consequence، exposure، controls و uncertainty نیاز دارد. یک Defect امنیتی مهم میتواند از ده Typo پرریسکتر باشد؛ Density این تفاوت را خودکار نمیبیند. اولویت تست را در چارچوب تست مبتنی بر ریسک با Evidenceهای مکمل تعیین کنید.
آیا Defect Density شاخص پیشرو یا پسرو است؟
نسبت به Defectهای کشفشده در همان Window یک Outcome measure پسرو است؛ نسبت به Failure یا Escape آینده فقط یک Candidate پیشرو است که باید جداگانه اعتبارسنجی شود. طبق راهنمای شاخص پیشرو و پسرو در QA، Label به Outcome، Horizon، Population و Decision وابسته است؛ Density ذاتاً Predictive نیست.
کاهش Density موفقیت Process change را ثابت نمیکند
پس از TDD یا Refactoring، کاهش مشاهدهشده ممکن است از Scope، تیم، ابزار، Detection opportunity یا مخرج بیاید. Association را Cause ننامید. برای اثر Intervention، Baseline مناسب، Comparison/Counterfactual، predeclared outcomes و Guardrails لازم است؛ مسیر عملی در بهبود مستمر QA با Experiment آمده است.
هرگز Density را KPI فردی نکنید
Defect به سیستم، Requirement، Design، Code، Test، Integration و Operation مرتبط است. نسبتدادن Density به فرد باعث پنهانکردن Defect، تغییر State، Duplicate merge افراطی، افزودن LOC بیارزش یا پرهیز از کار سخت میشود. Contract باید people_scoring=false و کاربرد مجاز را در سطح Subject/Process محدود کند.
Gaming چگونه رخ میدهد؟
- Report نکردن یا دیر تأییدکردن Defect پیش از Cutoff
- تبدیل Defect به Improvement/Change request
- ادغام Defectهای مستقل به یک Canonical ID
- افزودن generated/vendor code به مخرج
- شکستن/ادغام Component برای تغییر Density
- کوتاهکردن Window یا حذف Source پرکشف
- تنزل Severity برای سبزکردن Stratum
- تغییر Counting tool بدون Bridge و حفظ تاریخچه
Countermetricهای ضروری
| ریسک تفسیر | Countermetric/Context |
|---|---|
| Density پایین از Detection ضعیف | Observation opportunity profile، risk-evidence coverage |
| Duplicate manipulation | Duplicate/reopen/reclassification rate |
| Denominator inflation | Generated/vendor/reused composition و size delta |
| Window نارس | Maturity coverage و late-report rate |
| شدت پنهان | Severity strata و critical-scenario evidence |
| Product impact | Failure/incident/exposure measures جدا |
| Data failure | Missing/join/late/freshness/schema metrics |
Dashboard خوب چه چیزی نشان میدهد؟
- Metric/Contract version، Subject، Artifact و Window
- Count خام Numerator، Denominator خام، واحد و Density
- Defect phase/source/state/severity strata
- Cutoff، maturity، provisional/late/missing و Data fitness
- Size method/tool، generated/vendor/reused composition
- Observation opportunity و Context changes
- Comparability state: COMPARABLE، LIMITED، NOT_COMPARABLE یا UNKNOWN
- Not claimed، Owner، next review و Correction history
رنگ بدون متن کافی نیست. Density ۱ و ۲ را کنار هم نمایش ندهید اگر Gate شکست خورده است؛ بهجای Rank، «NOT_COMPARABLE: window/size/detection mismatch» بنویسید. کاربر باید از عدد تا Defect set و Size snapshot Drill-down داشته باشد، با Access کنترلشده و بدون افشای دادهٔ حساس.
Action Policy را پیش از دیدن عدد بنویسید
action_policy: ACT-DD-v2 IF data_fitness != PASS THEN HOLD; repair measurement; do not rank ELSE IF comparability_state == NOT_COMPARABLE THEN segment/redesign; no better/worse claim ELSE IF predeclared_trigger == true THEN request bounded evidence review ELSE observe until next maturity cutoff automatic_refactor: false automatic_release_gate: false automatic_risk_acceptance: false people_scoring: false decision_authority: ROLE-QUALITY-DECISION
چرخهٔ عمر Measure
DRAFT → CONTRACT_REVIEW → SHADOW → ACTIVE → UNDER_REVIEW → RETIRED
↘ REJECTED ↘ CORRECTED
Revalidation triggers:
- Defect taxonomy/state/source change
- Size rule/tool/language/composition change
- Observation window or maturity change
- Detection process/environment change
- Data-quality breach or unexplained discontinuity
- Decision/information need change
Rebaseline و Migration
تغییر KLOC tool، Defect state یا Window، Series را میشکند. در صورت امکان دورهٔ overlap را با هر دو Contract محاسبه و Bridge analysis کنید؛ در غیر این صورت Series جدید آغاز و Break marker ثبت کنید. اعداد قدیمی را با تعریف تازه بازنویسی نکنید مگر Recompute کامل، نسخهدار و قابلردیابی باشد.
Correction بدون Silent edit
correction_id: COR-DD-042-02 corrects: DD-SYN-042-v1 / SNAP-SYN-DD-042 reason: generated code was incorrectly included in denominator old_value: 1.0 defects/KLOC new_value: 1.5 defects/KESLOC affected_subjects: [COMP-B] affected_decisions: [DEC-SYN-042] old_comparability: COMPARABLE new_comparability: NOT_COMPARABLE issued_at: 2026-08-16T09:00:00Z superseding_artifacts: [DD-SYN-042-v2, SNAP-SYN-DD-043] silent_edit: false
نقشها و اختیارها
| نقش قابلیتمحور | مسئولیت | اختیار پیشفرض ندارد |
|---|---|---|
| Defect steward | Taxonomy، identity، state، duplicate | تغییر Size برای نتیجهٔ مطلوب |
| Size steward | Artifact scope، counting rule/tool | حذف Defect از Numerator |
| Metric steward | Contract، Snapshot، computation، lineage | Risk acceptance/Release |
| Domain reviewer | Boundary، attribution، interpretation | تأیید مستقل کار خودش |
| Decision authority | Information need، Trigger، Action | بازنویسی Evidence |
| Independent reviewer | Comparability، gaming، reproducibility | مالکیت Product decision |
Automation و AI چه مرزی دارند؟
- Automation میتواند Schema، canonical ID، State، Window، Dedup، Join، Size rule و Arithmetic را قطعی کنترل کند.
- Pipeline باید Contract mismatch را HOLD کند؛ فرمول صحیح روی دادهٔ ناهمسان کافی نیست.
- AI میتواند Defectهای مشکوک به Duplicate یا توضیح Dashboard پیشنهاد کند، نه اینکه Evidence را حذف یا State را نهایی کند.
- LLM نباید Benchmark بسازد، علت اعلام کند، افراد را رتبه دهد یا Release decision بگیرد.
- هر پیشنهاد AI باید مدل/نسخه، Prompt boundary، provenance، Confidence محدود و Human review داشته باشد.
امنیت و حریم خصوصی دادهٔ نقص
Ticketها ممکن است Payload، Log، Screenshot، نام کاربر، شناسهٔ حساب، IP، Token یا جزئیات آسیبپذیری داشته باشند. برای Density فقط canonical ID، classification و روابط حداقلی لازم است. Need-to-know access، redaction، retention، export audit و restricted-security queue را تعریف کنید. این مقاله مشاورهٔ حقوقی یا امنیتی نیست.
آزمایش اجرایی: کسر درست، مقایسهٔ غلط
Fixture زیر کاملاً ساختگی، آفلاین و غیرقابلتعمیم است. Checker سطحی فقط Arithmetic را میسنجد و `COMPARISON_VALID` میگوید. ممیزی قرارداد ۵۸ Rule دارد؛ Rule آخر People scoring را منع میکند و چون مقدار false است، نسخهٔ خام دقیقاً ۵۷ Finding میگیرد. تعداد Ruleها Benchmark بلوغ نیست.
const draft = {
modules: [
{id: "A", defects: 4, kloc: 2},
{id: "B", defects: 6, kloc: 6}
],
declared_status: "COMPARISON_VALID",
people_scoring: false
};
const present = (v) =>
v !== undefined && v !== null &&
!(typeof v === "string" && v.trim() === "") &&
!(Array.isArray(v) && v.length === 0);
const rules = [
["DD-01 review_id", x => present(x.review_id)],
["DD-02 revision", x => present(x.revision)],
["DD-03 supersedes", x => present(x.supersedes)],
["DD-04 information_need", x => present(x.information_need)],
["DD-05 decision_ref", x => present(x.decision_ref)],
["DD-06 decision_authority", x => present(x.decision_authority)],
["DD-07 decision_due", x => present(x.decision_due)],
["DD-08 not_deciding", x => present(x.not_deciding)],
["DD-09 metric_id", x => present(x.metric_id)],
["DD-10 metric_unit", x => present(x.metric_unit)],
["DD-11 subject_population", x => present(x.subject_population)],
["DD-12 artifact_snapshot", x => present(x.artifact_snapshot)],
["DD-13 defect_definition", x => present(x.defect_definition)],
["DD-14 eligible_states", x => present(x.eligible_states)],
["DD-15 defect_identity", x => present(x.defect_identity)],
["DD-16 duplicate_rule", x => present(x.duplicate_rule)],
["DD-17 reopen_rule", x => present(x.reopen_rule)],
["DD-18 discovery_phase", x => present(x.discovery_phase)],
["DD-19 discovery_sources", x => present(x.discovery_sources)],
["DD-20 observation_window", x => present(x.observation_window)],
["DD-21 attribution_rule", x => present(x.attribution_rule)],
["DD-22 severity_vocabulary", x => present(x.severity_vocabulary)],
["DD-23 numerator_exclusions", x => present(x.numerator_exclusions)],
["DD-24 size_method", x => present(x.size_method)],
["DD-25 size_tool_version", x => present(x.size_tool_version)],
["DD-26 size_scope", x => present(x.size_scope)],
["DD-27 size_snapshot", x => present(x.size_snapshot)],
["DD-28 blank_comment_rule", x => present(x.blank_comment_rule)],
["DD-29 generated_rule", x => present(x.generated_rule)],
["DD-30 vendored_rule", x => present(x.vendored_rule)],
["DD-31 reused_rule", x => present(x.reused_rule)],
["DD-32 language_composition", x => present(x.language_composition)],
["DD-33 minimum_denominator", x => present(x.minimum_denominator)],
["DD-34 zero_denominator_policy", x => present(x.zero_denominator_policy)],
["DD-35 cutoff", x => present(x.cutoff)],
["DD-36 maturity_rule", x => present(x.maturity_rule)],
["DD-37 data_snapshot", x => present(x.data_snapshot)],
["DD-38 source_versions", x => present(x.source_versions)],
["DD-39 query_digest", x => present(x.query_digest)],
["DD-40 missing_policy", x => present(x.missing_policy)],
["DD-41 late_policy", x => present(x.late_policy)],
["DD-42 join_policy", x => present(x.join_policy)],
["DD-43 data_fitness", x => present(x.data_fitness)],
["DD-44 observation_opportunity", x => present(x.observation_opportunity)],
["DD-45 test_scope_context", x => present(x.test_scope_context)],
["DD-46 detection_channels", x => present(x.detection_channels)],
["DD-47 comparability_profile", x => present(x.comparability_profile)],
["DD-48 comparability_state", x => present(x.comparability_state)],
["DD-49 uncertainty_method", x => present(x.uncertainty_method)],
["DD-50 small_denominator_policy", x => present(x.small_denominator_policy)],
["DD-51 zero_defect_interpretation", x => present(x.zero_defect_interpretation)],
["DD-52 countermetrics", x => present(x.countermetrics)],
["DD-53 not_claimed", x => present(x.not_claimed)],
["DD-54 action_policy", x => present(x.action_policy)],
["DD-55 revalidation_triggers", x => present(x.revalidation_triggers)],
["DD-56 expiry", x => present(x.expiry)],
["DD-57 correction_policy", x => present(x.correction_policy)],
["DD-58 people_scoring_prohibited", x => x.people_scoring !== true]
];
const density = (m) => m.defects / m.kloc;
const findings = (x) => rules.filter(([, ok]) => !ok(x)).map(([id]) => id);
console.log("SUPERFICIAL", draft.modules.map(m => [m.id, density(m)]), draft.declared_status);
console.log("CONTRACT", findings(draft).length ? "HOLD" : "READY", findings(draft).length);
const corrected = {
review_id: "SYN-DD-042", revision: "v1", supersedes: "none:first-revision",
information_need: "select comparable components for bounded evidence review",
decision_ref: "DEC-SYN-042", decision_authority: "ROLE-QUALITY-DECISION",
decision_due: "2026-09-01T09:00:00Z",
not_deciding: ["release", "risk-acceptance", "refactor", "people-performance"],
metric_id: "M-OBS-DD-v3", metric_unit: "confirmed unique defects/KESLOC",
subject_population: "POP-SYN-COMP-v2", artifact_snapshot: "ART-SYN-b42-C42",
defect_definition: "DEF-CONTRACT-v4", eligible_states: ["CONFIRMED", "RESOLVED", "CLOSED"],
defect_identity: "canonical_defect_id", duplicate_rule: "one canonical defect",
reopen_rule: "same ID unless independently confirmed", discovery_phase: "system-test",
discovery_sources: ["manual-session", "deterministic-suite"],
observation_window: "2026-07-01/2026-07-31", attribution_rule: "affected component at C42",
severity_vocabulary: "SEV-SYN-v2; stratify, no weights",
numerator_exclusions: ["DUPLICATE", "REJECTED", "ENVIRONMENT_ISSUE"],
size_method: "KESLOC-RULE-v2", size_tool_version: "SYN-LOC-v2",
size_scope: "src/checkout/**", size_snapshot: "SIZE-SYN-C42",
blank_comment_rule: "exclude blank and comment-only", generated_rule: "exclude/report",
vendored_rule: "exclude/report", reused_rule: "include only owned subject code",
language_composition: {typescript: 1.0}, minimum_denominator: "1 KESLOC",
zero_denominator_policy: "INVALID/HOLD", cutoff: "2026-08-15T00:00:00Z",
maturity_rule: "14d after window close", data_snapshot: "SNAP-SYN-DD-042",
source_versions: ["TRACKER-v5", "LOC-RULE-v2"], query_digest: "sha256:fictional",
missing_policy: "UNKNOWN; never zero", late_policy: "provisional then correction",
join_policy: "canonical component ID or quarantine", data_fitness: "PASS",
observation_opportunity: "same 30d system+exploratory profile",
test_scope_context: "same risk strata and synthetic environment",
detection_channels: ["manual-session", "deterministic-suite"],
comparability_profile: "CMP-DD-v2", comparability_state: "COMPARABLE_WITH_LIMITATIONS",
uncertainty_method: "show raw counts/denominators and preregistered interval",
small_denominator_policy: "do not rank below 1 KESLOC",
zero_defect_interpretation: "zero observed only; no absence claim",
countermetrics: ["maturity", "duplicate-rate", "size-composition", "data-health"],
not_claimed: ["latent-defects", "quality", "cause", "risk", "release"],
action_policy: "bounded evidence review only", revalidation_triggers: ["contract-change", "data-breach"],
expiry: "2026-10-01T09:00:00Z", correction_policy: "supersede; no silent edit",
people_scoring: false
};
const correctedFindings = findings(corrected);
console.log("CORRECTED", correctedFindings.length ? "HOLD" : "READY_FOR_DENSITY_REVIEW", correctedFindings.length);
خروجی مستقل Fixture
SUPERFICIAL [ [ 'A', 2 ], [ 'B', 1 ] ] COMPARISON_VALID CONTRACT HOLD 57 CORRECTED READY_FOR_DENSITY_REVIEW 0
نسخهٔ خام Arithmetic درست دارد اما هر ۵۷ فیلد ساختاری لازم را از دست داده است؛ تنها Rule منع People scoring پاس میشود. نسخهٔ اصلاحشده صفر Finding ساختاری دارد و حتی وضعیتش `COMPARABLE_WITH_LIMITATIONS` است. این نتیجه صحت Defectها، کفایت Detection، صحت Size، مناسببودن روش عدمقطعیت، کیفیت، Cause، Risk، Refactor یا Release را ثابت نمیکند.
آزمایشگاه آفلاین Checkout فارسی
یک Lab جدا از Production بسازید: Order، PaymentAttempt، PSP Stub جعلی، Callback، Ledger، Reconciliation و اعلان ساختگی. Defectهای تکرار Callback، timeout پیش/پس از Fake commit، retry، late/out-of-order event، rounding نمایشی و mismatch دفترکل را با Canonical ID ثبت کنید. سپس عمداً Duplicate، Reopen، Defect نارس، Component گمشده و generated code را وارد کنید تا Gate آنها را بگیرد.
lab_id: SYN-IR-CHECKOUT-DD-01
network: disabled
production_data: forbidden
identities: [Tenant, Order, Attempt, Event, Defect, Component, Build, Snapshot]
canonical_currency: fictional IRR only
toman_view: presentation-only and explicitly labelled
digits: [Persian, Arabic, Latin]
unicode_pairs: [ی/ي, ک/ك]
event_time: ISO-8601 UTC
display_timezone: Asia/Tehran
jalali_date: presentation-only
forbidden: [real company, user, order, PSP, bank, money, PAN, CVV2, OTP,
account, mobile, email, IP, cookie, token, credential, log, screenshot]
claims: synthetic, non-representative, no legal/financial/security conclusion
IRR ساختگی را Canonical نگه دارید و تومان را فقط View صریحاً برچسبدار بدانید؛ Currency normalization نباید Defect identity را بیصدا تغییر دهد. ارقام فارسی/عربی/لاتین، ی/ی، ک/ک و RTL/LTR را در Dedup و Search آزمایش کنید. UTC زمان Canonical، Asia/Tehran نمایش و جلالی فقط Presentation است. هیچ ادعای بانکی، مالی، حقوقی، امنیتی یا نمایندگی بازار ایران مجاز نیست.
Pilot سیروزهٔ Measurement Contract
- روز ۱ تا ۵: Information need، Decision، Defect/Size contract و Not claimed را Review کنید.
- روز ۶ تا ۱۰: Canonical IDs، Source/State/Window، Artifact/Size snapshot و Data gate را Shadow کنید.
- روز ۱۱ تا ۱۸: Density را بدون Rank یا Action خودکار محاسبه و Numerator/Denominator را بازتولید کنید.
- روز ۱۹ تا ۲۴: maturity، late/duplicate/join، Detection opportunity و Comparability matrix را بررسی کنید.
- روز ۲۵ تا ۳۰: Independent review؛ سپس REJECT، REDESIGN، EXTEND_SHADOW یا LIMITED_ACTIVE را ثبت کنید.
اگر Observation Window یا Maturity بیشتر از سی روز است، Pilot را تا بلوغ واقعی ادامه دهید. «اطلاعات هنوز کافی نیست» خروجی معتبر است. Measure را ابتدا برای یادگیری فعال کنید، نه برای هدفگذاری، پاداش، Release gate یا رتبهبندی.
ضدالگوهای چگالی نقص
- فرمول Total defects/KLOC بدون Defect و Size contract
- حذف واژهٔ Observed و ادعای نقصهای واقعی/پنهان
- مقایسهٔ Internal، System و Post-release defects در یک عدد
- مقایسهٔ Window هفتروزه با ششماهه
- شمارش OPEN، REJECTED و Duplicate بدون Rule
- استفاده از generated/vendor code برای بزرگکردن مخرج
- مخلوطکردن زبانها و Toolهای شمارش بدون Composition
- تبدیل Defects/transaction به Defects/KLOC یا بالعکس
- وزن دلخواه Severity و پنهانکردن Count خام
- اعلام صفر observed بهعنوان بدونباگ
- رتبهبندی Component کوچک با یک Defect
- عدد عمومی ۰٫۵ تا ۲ بهعنوان استاندارد صنعت
- تبدیل Trend نزولی به اثبات بلوغ/TDD
- اعلام Complexity/Coverage ضعیف بهعنوان Cause
- استفاده بهعنوان KPI فردی یا مبنای پاداش
- Rebaseline یا Silent edit برای سبزکردن Dashboard
چکلیست Owner پیش از انتشار Density
- Information need، Decision، Authority و Due روشناند.
- Metric ID/version و واحد Canonical ثبت شدهاند.
- Subject، Artifact، Build/Release و Population ثابتاند.
- Defect definition/Basis و Eligible states نسخه دارند.
- Canonical ID، Duplicate و Reopen rule مشخصاند.
- Discovery phase/source و Attribution rule ثبت شدهاند.
- Observation Window، Cutoff و Maturity جدا هستند.
- Severity Stratified است و وزن دلخواه پنهان ندارد.
- Size method/tool/version/scope/snapshot پایدارند.
- Blank/comment/generated/vendor/reused rules روشناند.
- Language composition و Minimum denominator ثبت شدهاند.
- Snapshot/Query digest/Source versions قابلبازتولیدند.
- Missing/Late/Join/Dedup/Freshness Gate پاس شده است.
- Observation opportunity و Detection channels همساناند.
- Comparability matrix پیش از Rank پاس شده است.
- Count و Denominator خام کنار Rate دیده میشوند.
- Uncertainty/small denominator/zero policy وجود دارد.
- Countermetricها، limitations و Not claimed نمایش داده شدهاند.
- People scoring و تصمیم خودکار Release/Risk ممنوعاند.
- Revalidation، Expiry، Migration و Correction policy کاملاند.
پرسشهای متداول درباره چگالی نقص نرمافزار
فرمول چگالی نقص دقیقاً چیست؟
فرمول عمومی تعداد نقصهای یکتا، مشاهدهشده و واجدشرایط تقسیم بر Size واجدشرایط است. مثال: چهار Defect تأییدشده بر ۲ KESLOC برابر ۲ Defect/KESLOC. اما فرمول فقط با Defect/Size contract، Window، Cutoff، Maturity و واحد نسخهدار معنا دارد.
آیا چگالی نقص پایین یعنی کیفیت بالا؟
خیر. Density پایین میتواند از نقص کمتر، تست/Telemetry ضعیفتر، Window کوتاه، Outcome نارس، Duplicate merge افراطی یا مخرج بزرگ ناشی شود. این Measure فقط نرخ نقصهای مشاهدهشده را در Scope محدود گزارش میکند و باید با Detection opportunity، Data health و کیفیتهای دیگر خوانده شود.
استاندارد قابلقبول Defect/KLOC چند است؟
عدد جهانی معناداری وجود ندارد. Domain، Phase، Severity، Defect definition، Size rule، Language، Observation Window و Detection opportunity تفاوت دارند. فقط Baseline یا Benchmark با Data dictionary و Protocol قابلمقایسه استفاده کنید؛ هیچ بازهٔ بیمنبع را Release gate نکنید.
KLOC بهتر است یا Function Point؟
هیچکدام همیشه بهتر نیست. KLOC به زبان و Counting rule حساس است؛ Function Point به Boundary، روش و Counter expertise وابسته است. روش را از Information need انتخاب، Contract کنید و Seriesهای با واحد متفاوت را ادغام نکنید. تغییر روش نیازمند Bridge یا شروع Series تازه است.
آیا میتوان با چگالی نقص ماژولها یا تیمها را رتبهبندی کرد؟
تیمها را نباید رتبهبندی کرد. Componentها نیز فقط پس از پاس کامل Comparability Gate و با نمایش Count، Size، uncertainty، Observation opportunity و Risk context برای Investigation محدود قابلمقایسهاند. Density بهتنهایی Cause، Risk، کیفیت یا مسئولیت فردی را نشان نمیدهد.
جمعبندی: قبل از Density، حق مقایسه را ثابت کنید
چگالی نقص یک کسر ساده با قرارداد پیچیده است. Numerator باید نقصهای یکتا و واجدشرایط را در Phase/Source/Window مشخص بشمارد؛ Denominator باید Size یا Exposure نسخهدار همان Scope باشد؛ Snapshot باید بالغ و سالم باشد؛ Comparability Gate باید قبل از هر Rank پاس شود.
عدد را «Observed» بنامید، Count و Size خام را نشان دهید، Detection opportunity و عدمقطعیت را پنهان نکنید و صفر را Absence نخوانید. اگر Contractها فرق دارند، پاسخ حرفهای `NOT_COMPARABLE` است. Measure خوب قاضی کیفیت نیست؛ Evidence محدودی است که سؤال بعدی را دقیقتر میکند و تاریخچهٔ تصحیح خود را حفظ میکند.

