Ownership, Tech Debt & Refactoring
Analyzing code ownership patterns, assessing technical debt severity, and identifying refactoring candidates.
Ownership and Knowledge Silo Analysis
Identifying bus-factor risks
Find critical infrastructure code with ownership concentration, metadata only
Tool parameters
{
"query": "critical infrastructure",
"rerank": "ownership",
"metaOnly": true,
"limit": 30
}
What to look for in results:
| Signal | Risk level | Meaning |
|---|---|---|
dominantAuthorPct >= 90 + contributorCount == 1 | Critical | Single person wrote and maintains this code |
dominantAuthorPct >= 70 + contributorCount == 2 | High | One person dominates, one occasional contributor |
dominantAuthorPct < 50 + contributorCount >= 4 | Low | Distributed ownership, healthy bus factor |
Combining ownership with churn
The most dangerous combination: knowledge silo + high churn + high bug-fix rate. One person owns code that keeps breaking.
Find single-owner code with high bug-fix rates in authentication
Tool parameters
{
"query": "authentication authorization access control",
"rerank": {
"custom": {
"similarity": 0.2,
"knowledgeSilo": 0.3,
"bugFix": 0.25,
"chunkChurn": 0.25
}
},
"pathPattern": "**/auth/**"
}
Action matrix:
| Ownership | Churn | Bug Fix Rate | Action |
|---|---|---|---|
| Silo (1 author) | High | High | Immediate risk — schedule pair programming, knowledge transfer |
| Silo (1 author) | Low | Low | Monitor — stable but still a bus factor |
| Distributed (4+ authors) | High | High | Quality problem but no knowledge risk |
| Distributed (4+ authors) | Low | Low | Healthy — no action needed |
Tech Debt Assessment: Beyond Age
Tech debt is not just "old code." It's old code that keeps requiring patches. The techDebt preset captures this:
Find legacy code older than 60 days with high churn in core domain, metadata only
Tool parameters
{
"query": "core domain logic",
"rerank": "techDebt",
"filter": {
"must": [{ "key": "git.ageDays", "range": { "gte": 60 } }]
},
"metaOnly": true,
"limit": 30
}
Scoring tech debt severity
Combine signals to assess severity — not all old code is debt:
| Pattern | Severity | Description |
|---|---|---|
ageDays > 180 + commitCount > 15 + bugFixRate > 40% | Critical | Old code that keeps breaking and getting patched |
ageDays > 180 + commitCount > 15 + bugFixRate < 15% | Low | Old code that changes for features, not fixes — active evolution |
ageDays > 180 + commitCount < 3 + bugFixRate = 0% | None | Old stable code — not debt, just mature |
ageDays > 90 + relativeChurn > 5.0 + churnVolatility > 30 | High | Code has been substantially rewritten multiple times with irregular bursts |
The relativeChurn advantage
Raw commitCount is misleading for debt assessment. A 2000-line utility file with 20 commits might be fine. A 50-line config file with 20 commits (relativeChurn = 8.0+) is a design problem.
Use relativeChurn for debt ranking:
relativeChurn range | Interpretation |
|---|---|
< 0.5 | Stable, well-designed |
0.5 - 2.0 | Normal development activity |
2.0 - 5.0 | Moderate churn — review if bugFixRate is high |
> 5.0 | Code has been rewritten multiple times — strong debt signal |
This aligns with Nagappan & Ball's finding that relative churn is the strongest single defect predictor.
Refactoring Candidates: Size + Churn + Quality
The best refactoring candidates are large functions with high chunk-level churn and high bug-fix rates:
Find large, high-churn request handlers and processors as refactoring candidates
Tool parameters
{
"query": "request handler processor controller",
"rerank": "refactoring",
"metaOnly": true,
"limit": 20
}
Prioritization criteria
| Criterion | Metric | Why it matters |
|---|---|---|
| Function size | chunkSize (lines) | Large functions are harder to understand and test |
| Chunk churn | chunkChurnRatio | If one function absorbs most of the file's churn, it needs splitting |
| Bug density | chunkBugFixRate | High fix rate = function is structurally fragile |
| Volatility | churnVolatility | Irregular bursts indicate reactive patching |
| Relative churn | relativeChurn | Size-normalized — strongest defect predictor |
Distinguishing refactoring from tech debt
Tech debt and refactoring overlap but serve different purposes:
| Analysis | Focus | Key signal | Goal |
|---|---|---|---|
Tech debt (techDebt preset) | File age + accumulation | ageDays + commitCount + bugFixRate | Identify legacy code needing modernization |
Refactoring (refactoring preset) | Function size + structure | chunkChurnRatio + chunkSize + chunkBugFixRate | Identify specific functions to split or redesign |
A 2-month-old 200-line function with 8 bug fixes is a refactoring candidate (young, badly structured) but not tech debt (not old). An 18-month-old file with steady patches is tech debt (accumulated cruft) but refactoring might target only one function within it.