From harness-claude
> Analyze structural health of the codebase and surface problems before they become incidents.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Analyze structural health of the codebase and surface problems before they become incidents.
Runs 7-phase analysis of TypeScript codebases using typegraph-mcp tools like ts_dependency_tree and ts_import_cycles, producing architectural report for onboarding or overviews.
Assesses codebase health for legacy projects by analyzing complexity, dependencies, dead code, tech debt, and git hotspots. Produces per-module health scores and prioritized rescue plans.
Visualizes project dependency graphs across domains, detects circular dependencies, and analyzes cross-domain coupling in Python, JS/TS, and Go codebases. Use before refactoring, architecture reviews, or adding domains.
Share bugs, ideas, or general feedback.
Analyze structural health of the codebase and surface problems before they become incidents.
A knowledge graph at .harness/graph/ enables full analysis. If no graph exists,
the skill uses static analysis fallbacks (see Graph Availability section).
Run harness scan to enable graph-enhanced analysis.
Before starting, check if .harness/graph/graph.json exists.
If graph exists: Check staleness — compare .harness/graph/metadata.json
scanTimestamp against git log -1 --format=%ct (latest commit timestamp).
If graph is more than 2 commits behind (git log --oneline <scanTimestamp>..HEAD | wc -l),
run harness scan to refresh before proceeding. (Staleness sensitivity: High)
If graph exists and is fresh (or refreshed): Use graph tools as primary strategy.
If no graph exists: Output "Running without graph (run harness scan to
enable full analysis)" and use fallback strategies for all subsequent steps.
Query the graph for five key structural indicators:
Hub detection: Find nodes with high fan-in (>10 inbound imports edges).
query_graph(rootNodeIds=[all file nodes], includeEdges=["imports"])
Hubs are single points of failure — changes to them have outsized blast radius.
Orphan detection: Find file nodes with zero inbound imports edges that are not entry points.
get_relationships(nodeId=<file>, direction="inbound")
Orphans may be dead code or missing from the module system.
Cycle detection: Use check_dependencies to find circular import chains.
Cycles create fragile coupling — any change in the cycle affects all members.
Deep chain detection: Find import chains longer than N hops (default: 7).
query_graph(rootNodeIds=[entry points], maxDepth=10, includeEdges=["imports"])
Deep chains are fragile — a change at the bottom propagates unpredictably.
Module cohesion: For each module (directory), count internal vs external edges. Low internal cohesion (many external edges, few internal) suggests misplaced code.
When no graph is available, use static analysis to approximate structural metrics:
import/require statements. Parse each to extract the imported path. Build an adjacency list mapping each file to its imports.index.*, not in package.json main/exports). Use glob to find all source files, then subtract those that appear as import targets.check_dependencies CLI — this works without a graph and can detect layer violations.Fallback completeness: ~60% — cannot compute transitive depth beyond what import parsing reveals; coupling metrics are approximate.
detect_anomalies to identify structural irregularities (orphaned modules, unusual coupling patterns) that indicate dependency health issues.Compute a weighted health score (0-100):
| Metric | Weight | Scoring |
|---|---|---|
| Hubs (>10 fan-in) | 25% | 0 hubs = 100, 1-3 = 70, 4-6 = 40, >6 = 10 |
| Orphans | 20% | 0 = 100, 1-5 = 80, 6-15 = 50, >15 = 20 |
| Cycles | 25% | 0 = 100, 1 = 60, 2-3 = 30, >3 = 0 |
| Deep chains (>7) | 15% | 0 = 100, 1-3 = 70, >3 = 30 |
| Cohesion (avg) | 15% | >0.7 = 100, 0.5-0.7 = 70, <0.5 = 30 |
Grades: A (90-100), B (75-89), C (60-74), D (40-59), F (<40)
Check get_decay_trends to see how dependency health metrics have changed over time and whether current trends are improving or degrading.
For each problem found, generate a specific, actionable recommendation:
src/utils/helpers.ts (14 importers) into domain-specific utilities"src/legacy/old-parser.ts (0 importers, not an entry point)"src/types/shared.ts"src/services/ has 80% external edges — consider splitting"## Dependency Health Report
### Score: B (78/100)
### Metrics
| Metric | Count | Score |
|--------|-------|-------|
| Hubs (>10 fan-in) | 2 | 70/100 |
| Orphans | 3 | 80/100 |
| Cycles | 0 | 100/100 |
| Deep chains (>7) | 1 | 70/100 |
| Module cohesion | 0.62 avg | 70/100 |
### Top Issues
1. **Hub**: src/utils/helpers.ts — 14 importers (split recommended)
2. **Hub**: src/types/index.ts — 12 importers (acceptable for type barrel)
3. **Orphan**: src/legacy/old-parser.ts — 0 importers
4. **Deep chain**: entry→auth→user→db→pool→config→env→loader (8 hops)
### Recommendations
1. Split src/utils/helpers.ts into domain-specific modules
2. Investigate src/legacy/old-parser.ts for removal
3. Flatten auth chain by having auth import db directly
harness scan — Recommended before this skill for full graph-enhanced analysis. If graph is missing, skill uses static analysis fallbacks.harness validate — Run after acting on findings to verify project health.query_graph, get_relationships, and check_dependencies MCP tools.These are common rationalizations that sound reasonable but lead to incorrect results. When you catch yourself thinking any of these, stop and follow the documented process instead.
| Rationalization | Why It Is Wrong |
|---|---|
| "There are a few orphan files but they are probably test fixtures or configs, so I will skip investigating them" | Orphan detection explicitly excludes entry points. Files with zero inbound imports that are not entry points must be investigated. |
| "The cycle is between two closely related files, so it is not really a problem" | Cycles create fragile coupling where any change in the cycle affects all members. Even "related" files should not have circular dependencies. |
| "The health score is a B, which is good enough -- no need to act on the recommendations" | A hub with 14 importers is a single point of failure. "Good enough" scores mask specific structural risks that compound over time. |
Input: Scheduled weekly run on project root
1. METRICS — query_graph for hubs: 2 found (helpers.ts, index.ts)
get_relationships for orphans: 3 found
check_dependencies for cycles: 0 found
query_graph for deep chains: 1 found (8 hops)
Module cohesion average: 0.62
2. SCORE — Weighted score: 78/100 (Grade: B)
3. RECOMMEND — "Split helpers.ts (14 importers) into domain modules"
"Investigate old-parser.ts for removal (0 importers)"
"Flatten auth chain — 8 hops exceeds threshold"
Output:
Score: B (78/100)
Top issues: 2 hubs, 3 orphans, 1 deep chain
3 actionable recommendations generated