Help us improve
Share bugs, ideas, or general feedback.
From kookr-toolkit
Detect AI-induced architecture drift by measuring file-size distribution, layer-boundary violations, and dependency-graph corruption. Use to score structural health, spot drift hotspots, and produce a drift report.
npx claudepluginhub kookr-ai/kookr --plugin kookr-toolkitHow this skill is triggered — by the user, by Claude, or both
Slash command
/kookr-toolkit:architecture-drift-signalsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
How AI-generated codebases degrade — and how to measure it. Architecture drift is a **cumulative** failure pattern: no single commit is the culprit, but after 200 prompt sessions the layer boundaries have dissolved. Every individual change looked locally reasonable at review time.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
How AI-generated codebases degrade — and how to measure it. Architecture drift is a cumulative failure pattern: no single commit is the culprit, but after 200 prompt sessions the layer boundaries have dissolved. Every individual change looked locally reasonable at review time.
This skill gives you the quantitative signals, thresholds, and detection commands to measure drift before it becomes unrecoverable.
Three reinforcing root causes:
| Code | Root cause | Mechanism |
|---|---|---|
| RC01 | Local optimization | Each prompt session solves the immediate problem in the most convenient location. The AI has no cross-session memory of which layer a concept belongs in, so business logic lands in UI components, DB queries in route handlers, etc. |
| RC02 | Dependency-graph corruption | Drift manifests as cycles, cross-layer imports, and hub modules. Once cycles exist, every subsequent prompt has unpredictable blast radius — which accelerates further corruption. |
| RC03 | Structural entropy | Entropy only increases. The more drift has accumulated, the higher the cost of "doing it the right way", so under pressure the most convenient location wins — again. |
Implication: drift is self-reinforcing. The earlier you measure, the cheaper remediation is.
Oversized files are the clearest aggregate signal: each prompt session added logic to the most convenient file, and over time those files inflate past any coherent responsibility.
# Distribution of file sizes (TypeScript src/ tree)
find src -name "*.ts" -o -name "*.tsx" 2>/dev/null | \
grep -v -E '\.test\.ts|\.spec\.ts|__fixtures__' | \
xargs wc -l 2>/dev/null | grep -v total | \
awk '{
if ($1 < 100) small++
else if ($1 < 300) medium++
else if ($1 < 500) large++
else critical++
total++
}
END {
print "< 100 LOC (healthy):", small, "files"
print "100-300 LOC (acceptable):", medium, "files"
print "300-500 LOC (warning):", large, "files"
print "> 500 LOC (drift signal):", critical, "files"
printf "Drift ratio: %.1f%%\n", (critical/total)*100
}'
# Top 10 drift hotspots
find src -name "*.ts" -o -name "*.tsx" | \
grep -v -E '\.test\.ts|\.spec\.ts|__fixtures__' | \
xargs wc -l 2>/dev/null | sort -rn | head -11 | tail -10
Severity thresholds:
| Drift ratio (% of files > 500 LOC) | Severity | Interpretation |
|---|---|---|
| 0-5% | Healthy | Boundaries intact |
| 5-15% | Watch | Early drift; a few hotspots forming |
| 15-30% | Significant | Boundaries eroding; folder structure no longer reflects logic distribution |
| > 30% | Critical | Architecture has dissolved; folder names are misleading |
The top-10 largest files are the drift hotspots — where the most architectural violations have compounded. Read them first.
Example layer order (substitute your own — every project's layer naming differs). The pattern is "outer depends on inner only", with a thin shared protocol-types tier:
frontend → server → adapters → core
↓
(shared: protocol types only)
Violations to detect:
# Core importing outward (most severe — breaks isolation)
grep -rn "from ['\"]\.\./\(server\|adapters\|frontend\)" src/core/ 2>/dev/null
# Adapters importing server/frontend
grep -rn "from ['\"]\.\./\(server\|frontend\)" src/adapters/ 2>/dev/null
# Server importing frontend
grep -rn "from ['\"]\.\./frontend" src/server/ 2>/dev/null
# Business logic in UI components (React/TSX)
grep -rn "fetch\|axios\|prisma\.\|db\." --include="*.tsx" src/frontend/ 2>/dev/null | \
grep -v -E "import|//|\.test\.|\.stories\."
# DB queries / transport concerns in core (layer leak downward into domain)
grep -rn "fetch\|WebSocket\|http\.\|express\|hono" --include="*.ts" src/core/ 2>/dev/null | \
grep -v -E "import type|//|\.test\."
Severity thresholds:
| Finding | Severity |
|---|---|
Any core → outer runtime import | Critical (isolation broken) |
Any adapters → server/frontend runtime import | Critical |
Any direct DB/transport call inside core/ | Critical |
| Business logic (pricing, auth, validation rules) in UI components | Critical (testability destroyed) |
import type crossing layers | Minor (no runtime coupling) |
server → frontend imports | Major |
# Install-free circular-dep check (uses npx)
npx --yes madge --circular --extensions ts,tsx src/ 2>/dev/null
# Files with broad import surface (potential hub/god modules)
find src -name "*.ts" -o -name "*.tsx" | grep -v -E '\.test\.' | while read f; do
count=$(grep -c "^import" "$f" 2>/dev/null || echo 0)
echo "$count $f"
done | sort -rn | head -10
Severity thresholds:
| Count | Severity | Interpretation |
|---|---|---|
| 0 cycles | Healthy | DAG intact |
| 1-2 cycles | Major | Isolation compromised in those clusters |
| ≥ 3 cycles | Critical | Blast radius of any change is unpredictable |
| File with > 15 imports | Watch | Potential hub coupling many domains |
| File with fan-in > 10 | Watch | God module; change-magnet |
Combine the three signals into a single score (0-100, higher = worse):
drift_score = 40 * min(drift_ratio_pct / 30, 1.0) # FP001 weight: 40
+ 35 * layer_violations_severity_factor # FP002 weight: 35
+ 25 * cycle_severity_factor # FP006 weight: 25
where:
layer_violations_severity_factor = min(critical_violations / 5, 1.0)
cycle_severity_factor = min(cycle_count / 3, 1.0)
| Score | Band | Recommendation |
|---|---|---|
| 0-15 | Healthy | Monitor; no action |
| 16-40 | Watch | Address top-3 hotspots within the next few PRs |
| 41-70 | Stabilize | Stop adding features to the drift hotspots; break cycles; enforce boundaries via lint |
| 71-100 | Cap & Grow | Freeze legacy zone; new features in isolated modules with enforced boundaries |
These weights match the emphasis in the source guide (architecture drift weighted ~25% of the AI Chaos Index, file-size distribution called the "drift fingerprint").
Use this to estimate how far drift has progressed and place findings on a curve:
Week 1-4 Launch Folder structure reflects intent. Drift ratio ~0%.
Month 2 First violations A pricing calc lands in a UI component. Drift ratio ~5%.
Month 3 Velocity drops Largest file ~400 LOC. First cycle forms — undetected.
Month 4 Naming divergence Same concept named 3 ways. Onboarding cost rises.
Month 5 Folder lies Folder structure no longer matches actual logic distribution.
Month 6 Structural debt Drift ratio >15%, several cycles, business logic in >20 UI files.
Critical insight: the cost of remediation grows non-linearly — not because individual violations get harder to fix, but because they become interdependent.
| Observable pain | Drift mechanism that enables it |
|---|---|
| Fragile systems, unpredictable blast radius | Eroded boundaries (FP002) + cycles (FP006) |
| Regression fear | No layer isolation → changes leak across modules without tests catching it |
| Hidden technical debt | Structural entropy accumulates invisibly between commits |
| "Afraid to regenerate" | Custom logic intermixed with generated code because layer separation is gone |
Fixing drift is therefore a precondition for solving these other pains — not an optional cleanup.
architecture-drift-detector, architecture-smell-scanner, and dependency-graph-analyzer should reference this skill for thresholds and detection commands so their findings stay consistent.