Chapter 4.1: Technical Debt Grading (TDG)

Chapter Status: ✅ 100% Working (8/8 examples)

StatusCountExamples
✅ Working8All TDG features tested
⚠️ Not Implemented0Planned for future versions
❌ Broken0Known issues, needs fixing
📋 Planned0Future roadmap features

Last updated: 2025-09-08
PMAT version: pmat 2.68.0
Test-Driven: All examples validated in tests/ch04/test_tdg.sh

Understanding Technical Debt Grading

Technical Debt Grading (TDG) is PMAT’s flagship feature for comprehensive code quality assessment. Introduced in version 2.68.0, TDG provides a multi-dimensional analysis that goes beyond simple metrics to deliver actionable insights about code maintainability.

What is TDG?

TDG is a composite score ranging from 0.0 to 5.0 that quantifies technical debt by analyzing five orthogonal components:

  1. Complexity Factor (30% weight) - Cyclomatic and cognitive complexity
  2. Churn Factor (35% weight) - Code change frequency and magnitude
  3. Coupling Factor (15% weight) - Dependencies and architectural entanglement
  4. Duplication Factor (10% weight) - Code clones and similarity
  5. Domain Risk Factor (10% weight) - Business criticality and security considerations

These components combine to produce both a numerical score and a letter grade (A+ through F), making it easy to communicate code quality to both technical and non-technical stakeholders.

TDG Scoring System

Score Ranges and Severity

TDG ScoreSeverityGradeAction Required
0.0 - 0.5ExcellentA+Maintain quality
0.5 - 1.0Very GoodAMinor improvements
1.0 - 1.5GoodB+Monitor closely
1.5 - 2.0AcceptableBPlan refactoring
2.0 - 2.5WarningCRefactor soon
2.5 - 3.0CriticalDImmediate attention
3.0 - 5.0SevereFEmergency refactoring

The Five Components Explained

1. Complexity Factor (30%)

Measures both cyclomatic and cognitive complexity:

  • Cyclomatic Complexity: Number of linearly independent paths
  • Cognitive Complexity: Mental effort required to understand code
  • Nested Depth: Levels of control flow nesting

2. Churn Factor (35%)

Analyzes code volatility over time:

  • Change Frequency: How often the code changes
  • Change Magnitude: Size of changes
  • Author Count: Number of different contributors
  • Hot Spot Detection: Frequently modified complex code

3. Coupling Factor (15%)

Evaluates dependencies and architectural health:

  • Afferent Coupling: Incoming dependencies
  • Efferent Coupling: Outgoing dependencies
  • Instability Index: Ratio of efferent to total coupling
  • Circular Dependencies: Cyclic relationships

4. Duplication Factor (10%)

Identifies code clones and repetition:

  • Type 1: Exact duplicates
  • Type 2: Renamed/parameterized duplicates
  • Type 3: Modified duplicates
  • Type 4: Semantic duplicates

5. Domain Risk Factor (10%)

Assesses business and security criticality:

  • Security Patterns: Authentication, encryption, validation
  • Business Critical Paths: Payment, user data, compliance
  • External Integrations: Third-party API dependencies
  • Error Handling: Exception management quality

Basic TDG Analysis

Command Line Usage

# Basic TDG analysis of current directory
pmat analyze tdg .

# Analyze specific path
pmat analyze tdg src/

# Show only critical files (TDG > 2.5)
pmat analyze tdg . --critical-only

# Custom threshold filtering
pmat analyze tdg . --threshold 2.0

# Include component breakdown
pmat analyze tdg . --include-components

# Limit to top 10 files
pmat analyze tdg . --top-files 10

Example Output

📊 Technical Debt Grading Analysis
═══════════════════════════════════════════════════════════════════

Project: my-application
Files Analyzed: 247
Average TDG: 1.42 (Grade: B+)

Top Files by TDG Score:
┌──────────────────────────────────┬──────┬───────┬──────────────┐
│ File                             │ TDG  │ Grade │ Severity     │
├──────────────────────────────────┼──────┼───────┼──────────────┤
│ src/legacy/payment_processor.py │ 3.8  │ F     │ Critical     │
│ src/utils/data_transformer.py   │ 2.9  │ D     │ Critical     │
│ src/api/complex_handler.py      │ 2.4  │ C     │ Warning      │
│ src/models/user_validator.py    │ 1.8  │ B     │ Normal       │
│ src/services/email_service.py   │ 1.2  │ B+    │ Normal       │
└──────────────────────────────────┴──────┴───────┴──────────────┘

Distribution:
  A+ (0.0-0.5):  45 files (18.2%)  ████████
  A  (0.5-1.0):  82 files (33.2%)  ██████████████
  B+ (1.0-1.5):  67 files (27.1%)  ███████████
  B  (1.5-2.0):  35 files (14.2%)  ██████
  C  (2.0-2.5):  12 files (4.9%)   ██
  D  (2.5-3.0):  4 files (1.6%)    █
  F  (3.0+):     2 files (0.8%)    ▌

Component Breakdown Analysis

Understanding individual components helps target specific improvements:

# Show detailed component breakdown
pmat analyze tdg . --include-components --format json

Example Component Output

{
  "file": "src/legacy/payment_processor.py",
  "tdg_score": 3.8,
  "grade": "F",
  "severity": "critical",
  "components": {
    "complexity": {
      "value": 2.4,
      "cyclomatic": 45,
      "cognitive": 62,
      "max_depth": 8,
      "contribution": "63.2%"
    },
    "churn": {
      "value": 0.8,
      "changes_last_30d": 15,
      "unique_authors": 6,
      "contribution": "21.1%"
    },
    "coupling": {
      "value": 0.3,
      "afferent": 12,
      "efferent": 28,
      "instability": 0.7,
      "contribution": "7.9%"
    },
    "duplication": {
      "value": 0.2,
      "clone_percentage": 18.5,
      "similar_blocks": 4,
      "contribution": "5.3%"
    },
    "domain_risk": {
      "value": 0.1,
      "risk_patterns": ["payment", "pii_data"],
      "contribution": "2.6%"
    }
  },
  "recommendations": [
    "Extract complex nested logic into separate functions",
    "Implement proper error handling patterns",
    "Reduce coupling by introducing interfaces",
    "Consolidate duplicate payment validation logic"
  ]
}

Configuration

Project Configuration

# pmat.toml
[tdg]
enabled = true
critical_threshold = 2.5
warning_threshold = 1.5

[tdg.weights]
complexity = 0.30
churn = 0.35
coupling = 0.15
duplication = 0.10
domain_risk = 0.10

[tdg.output]
include_components = true
show_percentiles = true
top_files = 10
grade_system = true

[tdg.analysis]
parallel = true
cache_enabled = true
incremental = true

[tdg.thresholds]
max_cyclomatic_complexity = 10
max_cognitive_complexity = 15
max_nesting_depth = 4
max_coupling = 20
duplication_threshold = 0.15

Custom Domain Risk Patterns

# .pmat/domain-risk.yaml
high_risk_patterns:
  - pattern: "payment|billing|charge"
    risk_score: 1.0
    category: "financial"
    
  - pattern: "password|auth|token|secret"
    risk_score: 0.9
    category: "security"
    
  - pattern: "user_data|personal_info|pii"
    risk_score: 0.8
    category: "privacy"
    
  - pattern: "export|report|analytics"
    risk_score: 0.5
    category: "business"

critical_paths:
  - "src/payments/**"
  - "src/auth/**"
  - "src/user/personal/**"

Advanced Features

Transactional Hashed TDG System

PMAT 2.68+ includes enterprise-grade features for large-scale analysis:

# Use persistent storage backend
pmat analyze tdg . --storage-backend sled

# Priority-based analysis
pmat analyze tdg src/critical --priority high

# Incremental analysis with caching
pmat analyze tdg . --incremental --cache-enabled

MCP Integration

TDG is fully integrated with the Model Context Protocol:

{
  "name": "tdg_analyze_with_storage",
  "arguments": {
    "paths": ["src/", "lib/"],
    "storage_backend": "rocksdb",
    "priority": "critical",
    "include_components": true
  }
}

Performance Profiling

# Profile TDG analysis performance
pmat tdg performance-profile . --duration 30

# Generate flame graphs
pmat tdg flame-graph . --output tdg-flame.svg

CI/CD Integration

GitHub Actions

name: TDG Analysis

on:
  pull_request:
  push:
    branches: [main]

jobs:
  tdg-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install PMAT
        run: cargo install pmat
        
      - name: Run TDG Analysis
        run: |
          pmat analyze tdg . \
            --format json \
            --output tdg-report.json
            
      - name: Check TDG Thresholds
        run: |
          # Fail if any file has TDG > 3.0
          pmat analyze tdg . --threshold 3.0 || exit 1
          
      - name: Generate TDG Report
        run: |
          pmat analyze tdg . \
            --include-components \
            --format markdown > tdg-report.md
            
      - name: Comment PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('tdg-report.md', 'utf8');
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 📊 TDG Analysis Results\n\n${report}`
            });

Quality Gates

# Enforce quality gates in CI/CD
pmat quality-gate \
  --tdg-threshold 2.0 \
  --min-grade B \
  --fail-on-regression

Real-World Examples

Example 1: Legacy Code Assessment

# Analyze legacy module
pmat analyze tdg src/legacy/ --include-components

# Output
File: src/legacy/order_processor.py
  TDG Score: 3.2 (Grade: F)
  Components:
    Complexity: 1.8 (56%) - Cyclomatic: 42, Cognitive: 58
    Churn: 0.9 (28%) - 23 changes in 30 days
    Coupling: 0.3 (9%) - 35 dependencies
    Duplication: 0.15 (5%) - 22% duplicate code
    Domain Risk: 0.05 (2%) - Contains payment logic
    
  Critical Issues:
    - Deeply nested conditional logic (max depth: 7)
    - Multiple responsibilities in single class
    - Hardcoded business rules
    
  Recommendations:
    1. Extract payment validation to separate service
    2. Implement strategy pattern for order types
    3. Add comprehensive error handling
    4. Increase test coverage (current: 12%)

Example 2: Microservice Analysis

# Analyze microservices with custom config
cat > tdg-micro.toml << EOF
[tdg.weights]
complexity = 0.25
churn = 0.30
coupling = 0.25  # Higher weight for microservices
duplication = 0.10
domain_risk = 0.10
EOF

pmat analyze tdg services/ --config tdg-micro.toml

Example 3: Hotspot Detection

# Find high-churn, high-complexity files
pmat analyze tdg . \
  --include-components \
  --format json | \
  jq '.files[] | 
    select(.components.churn.value > 0.5 and 
           .components.complexity.value > 1.5) | 
    {file: .path, tdg: .tdg_score, grade: .grade}'

Interpreting TDG Results

Action Priority Matrix

TDG ScoreComplexityChurnAction
High (>2.5)HighHigh🔴 Immediate refactoring
High (>2.5)HighLow🟠 Plan refactoring
High (>2.5)LowHigh🟡 Add tests first
Low (<1.5)AnyAny🟢 Monitor only

Improvement Strategies

For High Complexity:

  • Extract methods to reduce cyclomatic complexity
  • Simplify conditional logic
  • Apply design patterns (Strategy, Chain of Responsibility)
  • Reduce nesting depth

For High Churn:

  • Stabilize requirements
  • Improve test coverage
  • Add documentation
  • Consider architectural changes

For High Coupling:

  • Introduce interfaces/protocols
  • Apply Dependency Inversion Principle
  • Use dependency injection
  • Implement facade pattern

For High Duplication:

  • Extract common functionality
  • Create shared libraries
  • Use template patterns
  • Implement DRY principle

Best Practices

1. Baseline Establishment

# Create baseline for tracking
pmat analyze tdg . --format json > tdg-baseline.json

# Compare against baseline
pmat analyze tdg . --compare-baseline tdg-baseline.json

2. Incremental Improvement

# Focus on worst files first
pmat analyze tdg . --top-files 5 --critical-only

# Track improvement over time
pmat analyze tdg . --trend --period 30d

3. Team Standards

# team-standards.toml
[tdg.quality_gates]
new_code_max_tdg = 1.5
legacy_code_max_tdg = 3.0
pr_regression_tolerance = 0.1

[tdg.requirements]
min_grade_for_production = "B"
min_grade_for_release = "B+"

Troubleshooting

Common Issues

High TDG Despite Simple Code

  • Check for high churn (frequent changes)
  • Review domain risk patterns
  • Verify weight configuration

Inconsistent Scores

  • Enable caching: --cache-enabled
  • Use storage backend for persistence
  • Check for concurrent modifications

Performance Issues

  • Use incremental analysis: --incremental
  • Enable parallel processing: --parallel
  • Limit scope: --top-files 20

Summary

Technical Debt Grading provides:

  • Comprehensive Assessment: Five orthogonal metrics for complete picture
  • Actionable Insights: Specific recommendations for improvement
  • Grade System: Easy communication with stakeholders
  • Enterprise Features: Scalable to large codebases
  • CI/CD Integration: Automated quality gates
  • Trend Analysis: Track improvement over time

TDG transforms code quality from abstract concept to measurable, manageable metric.

Next Steps