skills/dev-test-gaps/SKILL.md
This skill should be used when validating test coverage against requirements, after implementation tasks complete (Phase 5.5 of /dev workflow). Invoked automatically by dev-implement before review phase.
npx skillsauth add edwinhu/workflows dev-test-gapsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Announce: "Using dev-test-gaps (Phase 5.5) to validate test coverage against requirements."
Iteration topology: parallel fan-out (one test-gap-auditor per MISSING requirement)
Load shared enforcement:
Read ${CLAUDE_SKILL_DIR}/../../references/constraints/dev-common-constraints.md.
Before spawning each batch of test-gap-auditors, check remaining context (a large requirement set + parallel auditors can exhaust it):
| Level | Remaining | Action | |-------|-----------|--------| | Normal | >35% | Spawn next auditor(s) | | Warning | 25-35% | Finish the current auditor, write VALIDATION.md (status: draft), then invoke dev-handoff | | Critical | ≤25% | Write VALIDATION.md immediately, invoke dev-handoff — resume fresh |
At Warning/Critical: Read ${CLAUDE_SKILL_DIR}/../../skills/dev-handoff/SKILL.md and follow its instructions.
NEVER MODIFY IMPLEMENTATION CODE. TESTS ONLY OR ESCALATE. This is not negotiable.
Your job is to validate that tests exist for every requirement, and fill gaps by writing NEW tests. You do NOT fix bugs, refactor code, or touch implementation files.
| Allowed | NOT Allowed | |---------|-------------| | Read implementation code (for understanding) | Edit implementation code | | Write new test files | Modify existing implementation files | | Update existing test files (add cases) | "Quick fix" to make a test pass | | Create test fixtures/helpers | Change production code to be "more testable" | | Escalate implementation bugs | Silently work around implementation bugs |
If a test fails because the implementation is wrong, ESCALATE. Do not fix the implementation. </EXTREMELY-IMPORTANT>
1. READ requirements from .planning/SPEC.md
2. READ tasks from .planning/PLAN.md
3. SCAN test infrastructure (framework, config, patterns)
4. MAP each requirement → test coverage
5. CLASSIFY: COVERED / PARTIAL / MISSING
6. FILL gaps by spawning test-gap-auditor agent for MISSING requirements
7. PRODUCE .planning/VALIDATION.md with full coverage map
Read .planning/SPEC.md and extract every testable requirement:
For each requirement in SPEC.md:
- Extract the requirement ID (e.g., AUTH-01, UI-02) from the Requirements table
- Note the requirement description
- Note the scope (v1/v2/out-of-scope) — only v1 requirements need coverage
- Note the acceptance criteria from Success Criteria (mapped by ID)
Read .planning/PLAN.md and extract:
Output: A list of requirements to validate, each with acceptance criteria.
Detect the project's test setup:
# Detect test framework and config
ls package.json pyproject.toml Cargo.toml pixi.toml setup.cfg 2>/dev/null
Then read the relevant config to identify:
# Find test files
fd -e test.ts -e test.js -e spec.ts -e spec.js -e _test.py -e _test.go -e _test.rs . 2>/dev/null || fd test . tests/ __tests__/ spec/ test/ 2>/dev/null | head -30
Read 2-3 existing test files to understand patterns (naming, imports, assertions, fixtures).
Output: Test infrastructure summary table.
For each requirement extracted in Phase 1:
Search for test coverage:
Read candidate test files to confirm they actually exercise the requirement (not just mention it)
Record the mapping: requirement ID -> test file -> specific test(s)
For each requirement, assign a classification:
| Classification | Criteria | |---------------|----------| | COVERED | Test exists, exercises the requirement, asserts correct behavior | | PARTIAL | Test exists but: missing edge cases, incomplete assertions, or only tests happy path | | MISSING | No test exercises this requirement |
These do NOT count as COVERED:
.skip()'d or @pytest.mark.skipFor each MISSING requirement, spawn a test-gap-auditor agent using subagent_type="workflows:test-gap-auditor":
Tool Restrictions (pass structurally, not just in prose): dispatch with an explicit allowed-tools list so the restriction is enforced by the harness, not honor-system —
allowed_tools=["Read", "Glob", "Grep", "Bash", "Write", "Edit"]
The auditor can Write/Edit test files ONLY. It MUST NOT modify implementation source code. If it discovers an implementation bug, it escalates — it does not fix. (Write/Edit are granted because tests are its deliverable; the test-files-only scope is enforced by the agent's own system prompt + the Auditor Constraints below.)
Agent prompt template:
You are a test auditor. Your ONLY job is to write tests.
REQUIREMENT: [requirement description from SPEC.md]
ACCEPTANCE CRITERIA: [from SPEC.md]
TEST FRAMEWORK: [detected framework]
TEST PATTERNS: [patterns from existing tests]
TEST DIRECTORY: [where tests live]
RULES:
1. Write a test that exercises this requirement
2. Follow the existing test patterns in the project
3. Run the test and confirm it passes
4. If the test FAILS because the implementation is buggy, DO NOT fix the implementation
- Report the failure
- Include the error output
- Mark as FAIL (escalated)
5. You have max 3 debug iterations to get the test working
- Iteration 1: Write and run test
- Iteration 2: Fix test issues (imports, setup, fixtures)
- Iteration 3: Final attempt
- After 3 failures: report FAIL (escalated)
OUTPUT: Report back with:
- Test file path
- Test name(s)
- PASS or FAIL (escalated)
- If FAIL: error output and whether it's a test issue or implementation bug
If the auditor reports that a test fails due to an implementation bug:
Fixing implementation bugs is dev-implement's job, not dev-test-gaps'. </EXTREMELY-IMPORTANT>
Attempt 1: Write test → Run
PASS → Done (record as gap filled)
FAIL (test bug) → Fix test → Attempt 2
FAIL (impl bug) → Escalate immediately
Attempt 2: Fixed test → Run
PASS → Done (record as gap filled)
FAIL (test bug) → Fix test → Attempt 3
FAIL (impl bug) → Escalate immediately
Attempt 3: Fixed test → Run
PASS → Done (record as gap filled)
FAIL → Escalate (max iterations)
| Orchestrator CAN (verification) | Orchestrator CANNOT (investigation — delegate it) |
|----------------------------------|----------------------------------------------------|
| Read the test file(s) the auditor wrote; run the test command | Debug a failing test's logic yourself |
| Record PASS / FAIL(escalated) into the coverage map | grep/rg implementation source to chase the bug |
| Re-dispatch an auditor for a still-MISSING requirement | Fix implementation code (that is dev-implement's job) |
If an auditor escalated an impl bug, record FAIL(escalated) — do NOT investigate or fix it here. </EXTREMELY-IMPORTANT>
After all requirements are mapped and gaps addressed, create .planning/VALIDATION.md:
---
status: [draft | validated | gaps_found]
coverage: [N/M requirements covered]
---
# Test Coverage Validation
## Test Infrastructure
| Property | Value |
|----------|-------|
| Framework | [detected] |
| Config | [path] |
| Run command | [command] |
## Coverage Map
| Req ID | Requirement | Test File | Status | Notes |
|--------|-------------|-----------|--------|-------|
| CAT-01 | [description] | [test path] | COVERED/PARTIAL/MISSING | [details] |
## Gaps Filled
| Req ID | Requirement | Test File | Result |
|--------|-------------|-----------|--------|
| CAT-01 | [description] | [new test path] | PASS/FAIL (escalated) |
## Summary
- Requirements: N total
- Covered: X
- Partial: Y
- Missing: Z (W filled, V escalated)
| Condition | Status |
|-----------|--------|
| All requirements COVERED, no escalations | validated |
| All requirements COVERED after gap-filling, no escalations | validated |
| Any PARTIAL or MISSING remain, or any escalations | gaps_found |
| Validation in progress | draft |
Checkpoint type: human-verify (VALIDATION.md status is machine-verifiable)
Validation passes (proceed to review):
.planning/VALIDATION.md exists with status validatedValidation fails (gaps found):
.planning/VALIDATION.md exists with status gaps_foundBefore setting status to validated, run the FULL test suite one final time:
# Run whatever test command was detected in Phase 2
[detected test command]
Only set status to validated after the full suite passes.
Run the canonical 5-step gate before chaining to dev-review:
1. IDENTIFY: `.planning/VALIDATION.md` exists; every requirement classified COVERED; no escalations.
2. RUN: execute the full test command from Phase 2 THIS turn (not "tests passed earlier").
3. READ: read the suite output — total / passed / failed / skipped counts.
4. VERIFY: zero failures, zero unexpected skips, all requirements COVERED.
5. CLAIM: only if 1-4 hold, write status: validated and chain to dev-review.
If any step fails, status stays gaps_found (or draft). A structural check (grep status: validated) is NOT the same as runtime evidence — see C3 (Structural vs Runtime Verification).
</EXTREMELY-IMPORTANT>
development
Build the meeting-level proxy-voting × ownership panel on the WRDS SGE grid — ISS N-PX fund votes reduced to (item × block) direction cells, joined to institutional and mutual-fund ownership. Use when working with risk.voteanalysis_npx, N-PX fund-level votes, ISS→CRSP fund linking, index/passive/active voting blocks, or a proxy-voting panel that needs ownership attached.
development
Use when "CRSP CIZ", "CRSP v2", "CRSP flat file format 2.0", "crsp.dsf_v2 / msf_v2", "StkDlySecurityData", "StkMthSecurityData", "StkSecurityInfoHist", "stocknames_v2", "DlyRet / MthRet / DlyPrc / MthPrc", "SHRCD or EXCHCD equivalent in new CRSP", "SIZ to CIZ migration", "CRSP data after 2024", "CRSP delisting returns", "CRSP cumulative adjustment factors", "CRSP index INDNO / INDFAM", or any CRSP stock/index query where the legacy SIZ column names no longer exist.
development
Use when linking or deduping datasets by entity name rather than a shared key — 'fuzzy match', 'fuzzy name matching', 'entity resolution', 'record linkage', 'match company/person names', 'dedupe entity names', 'name-based join', 'bridge identifiers' (CIK ↔ permno ↔ gvkey ↔ wficn ↔ EIN ↔ personid), or any use of char n-gram TF-IDF, cosine similarity on names, `sparse_dot_topn`, or RapidFuzz at scale.
development
Use when building a publication-quality table in Python — 'regression table', 'results table', 'summary statistics table', 'etable', 'coefplot', 'great_tables', 'GT', 'gt table', 'format a table for the paper', 'export table to LaTeX/HTML', significance stars, spanners, or column formatting for a table headed into a paper, slide deck, or notebook.