From harness-claude
Selects tests to run based on changed files using graph-based dependency analysis. Answers 'what tests should I run?' for code changes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:harness-test-advisorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Graph-based test selection. Answers: "I changed these files — what tests should I run?"
Graph-based test selection. Answers: "I changed these files — what tests should I run?"
on_pr triggers firecanary:canary-write-test for uncovered files surfaced by Coverage Audit)canary:canary-review-test)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 10 commits behind (git log --oneline <scanTimestamp>..HEAD | wc -l),
run harness scan to refresh before proceeding. (Staleness sensitivity: Medium)
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.
git diff --name-only to get changed file paths..ts, .tsx, .js, .jsx files (skip docs, config).For each changed file, use graph traversal to find test files:
Direct test coverage: Use get_impact to find test files that import the changed file.
get_impact(filePath="src/services/auth.ts")
→ tests: ["tests/services/auth.test.ts", "tests/integration/auth-flow.test.ts"]
Transitive test coverage: Use query_graph with depth 2 to find tests that import files that import the changed file.
query_graph(rootNodeIds=["file:src/services/auth.ts"], maxDepth=2, includeEdges=["imports"], bidirectional=true)
Co-change tests: Check co_changes_with edges for test files that historically change alongside the modified files.
When no graph is available, use naming conventions, import parsing, and git history:
foo.ts, search for:
foo.test.ts, foo.spec.ts (same directory)__tests__/foo.ts, __tests__/foo.test.tstests/ directory mirroring the source pathimport.*from in *.test.* and *.spec.* files). If a test file imports the changed file, it belongs in Tier 2 (if not already in Tier 1).git log --format="%H" --name-only to find test files that frequently change in the same commit as the target file. Files that co-change in >2 commits are co-change correlated.Fallback completeness: ~80% — naming conventions and imports catch most mappings; misses dynamic imports and indirect coverage.
Organize tests into three tiers:
Tier 1 — Must Run (direct coverage): Tests that directly import or test the changed files. These are most likely to catch regressions.
Tier 2 — Should Run (transitive coverage): Tests that cover code one hop away from the changed files. These catch indirect breakage.
Tier 3 — Could Run (related): Tests in the same module or that co-change with the modified files. Lower probability of failure but worth running if time permits.
## Test Advisor Report
### Changed Files
- src/services/auth.ts (modified)
- src/types/user.ts (modified)
### Tier 1 — Must Run (direct coverage)
1. tests/services/auth.test.ts — imports auth.ts
2. tests/types/user.test.ts — imports user.ts
### Tier 2 — Should Run (transitive)
3. tests/routes/login.test.ts — imports routes/login.ts → imports auth.ts
4. tests/middleware/verify.test.ts — imports middleware/verify.ts → imports auth.ts
### Tier 3 — Could Run (related)
5. tests/integration/auth-flow.test.ts — same module, co-changes with auth.ts
### Quick Run Command
npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes/login.test.ts tests/middleware/verify.test.ts
### Full Run Command (all tiers)
npx vitest run tests/services/auth.test.ts tests/types/user.test.ts tests/routes/login.test.ts tests/middleware/verify.test.ts tests/integration/auth-flow.test.ts
Activates when --audit is passed, OR when no diff is available AND the user's
language matches audit intent ("coverage gaps", "deep dive", "coverage plan",
"what's untested"). When this mode is selected, skip Phases 1–3 above and run
the audit phases below instead.
Call the canary_probe MCP tool once at the start of the audit. It returns
{ status: "available" | "degraded", version?, reason? } and never errors.
available — the deterministic canary CLI is usable; use canary_recommend_framework
for framework selection in Phase 3 (GAP REPORT).
degraded — the CLI is not usable (reason: not-installed, binary-missing,
exec-failed, or bad-output). Print one line:
canary CLI unavailable (
<reason>) — installcanary-test-clifor deterministic framework recommendations. Proceeding; framework picks fall back to the plugin.
Then skip canary_recommend_framework calls for the rest of the run. This does not
affect the plugin-based Quality Review in Phase 2 (canary:canary-review-test is a
separate Claude Code plugin, installed independently of the CLI).
.ts, .tsx, .js, .jsx under the
project's source roots (e.g., src/, packages/*/src/). Skip node_modules,
dist, build outputs, and fixtures.*.test.*, *.spec.*, and files under
__tests__/ and parallel tests/ directories.Phase 2: DISCOVER. With a
graph, prefer get_impact; without one, use naming conventions and import
parsing.covered (source files with at least one
matching test) and uncovered (source files with no matching test).canary:canary-review-test against the
test file. Collect its findings (missing edge cases, anti-patterns,
brittleness, oracle gaps).Emit a single report with three sections:
## Coverage Audit Report
### Uncovered Files (no test found)
| File | Lines | Priority | Suggested Action |
|------|-------|----------|------------------|
| src/services/billing.ts | 412 | high | canary:canary-write-test |
| src/utils/format.ts | 38 | low | canary:canary-write-test |
### Quality Gaps (from Quality Review, capped at 10 reviewed)
| Test File | Severity | Top Gap |
|-----------|----------|---------|
| tests/services/auth.test.ts | high | no failure-path assertions |
| tests/utils/date.test.ts | med | mock leaks across cases |
### Recommended Next Steps
- Generate tests for high-priority uncovered files via `canary:canary-write-test`.
- Resolve high-severity quality gaps via `canary:canary-review-test` follow-ups.
- For uncovered files, pick a framework first: when Phase 0 reported `available`, call
the `canary_recommend_framework` MCP tool with a prompt describing the file's purpose
(deterministic, no LLM round-trip) and put its `framework` in the Suggested Action.
When `degraded`, fall back to the `canary:canary-pick-framework` plugin.
harness scan — Recommended before this skill for full graph-enhanced analysis. If graph is missing, skill uses naming convention and import parsing fallbacks.harness validate — Run after acting on findings to verify project health.query_graph, get_impact, and get_relationships 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 |
|---|---|
| "Only the Tier 1 direct tests matter -- Tier 2 and Tier 3 are probably unnecessary" | Tier 2 tests catch indirect breakage one hop away. A change to auth.ts breaks login.ts which breaks login.test.ts. Skipping Tier 2 misses exactly the regressions hardest to debug. |
| "The changed file has no tests, but that is not my concern -- I just advise on which tests to run" | Coverage gaps must be flagged. When a changed file has no test coverage, the advisor reports it. Silently producing an empty test list gives false confidence. |
| "The graph is stale but I will use it anyway since some data is better than no data" | If the graph is more than 10 commits behind, refresh before proceeding. Staleness sensitivity is Medium for test advisor. |
Input: git diff shows src/services/auth.ts and src/types/user.ts modified
1. PARSE — 2 changed files identified (both .ts)
2. DISCOVER — get_impact(filePath="src/services/auth.ts")
query_graph with depth 2 for transitive tests
Tier 1: auth.test.ts, user.test.ts (direct imports)
Tier 2: login.test.ts, verify.test.ts (one hop away)
Tier 3: auth-flow.test.ts (co-change history)
3. PRIORITIZE — 5 tests across 3 tiers
Output:
Tier 1 (must run): 2 tests
Tier 2 (should run): 2 tests
Tier 3 (could run): 1 test
Quick command: npx vitest run auth.test.ts user.test.ts login.test.ts verify.test.ts
Coverage gaps: none
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeScouts test coverage gaps, creates test files, continues incomplete suites, tracks persistent coverage using project test config and git analysis.
Traces codepaths in git diffs, maps them against tests, scores coverage quality, and auto-generates tests for uncovered paths before shipping PRs.
Audits existing test suite alignment after code changes, identifying stale assertions, tests for deleted code paths, and coincidence tests. Use after any code modification.