agentleFS
dayvisonassisdayvisonassis/sdd-skills/skills/unit-test-validator/SKILL.md

unit-test-validator

Skill3 starsChanged 32 days agoMITView on GitHub

Use when a unit test file or folder of any project must be audited for conformance before it is trusted — dispatched by the evaluator or qa-preflight after a unit-test-writer correction or new test, or run directly by a user. Generic — reads the suites, the runner and the project's own rules from the test profile in the project's GATES.md. Read-only — never writes, fixes or runs tests.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Check EVERY rule from ../unit-test-writer/references/unit-rules.md:

    line 57
  2. Distinctive:

    Do not skip rules after finding criticals.

    line 93

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Unit Test Validator

Audit unit test files to ensure they comply with every rule the unit-test-writer enforces. Read-only: produce a compliance report; never modify test or production files, never execute tests (static analysis only).

The full rule set is in ../unit-test-writer/references/unit-rules.md — validate against it. Build its project profile from the project's GATES.md first: it says which suites, runner and language the rules apply to here, and names the project's own rules file, which is audited too. The suite's language file, ../unit-test-writer/references/languages/<language>.md, is part of the rules: resolve the language as unit-rules.md ("Language") says, and read that one file.

Scope: the unit suites the project profile names. Out of scope, reported as such: a file of an integration, e2e or visual suite.

INPUT

  • test_file_path (required) — test file or directory.
  • checklist_file_path (optional) — the checklist, for coverage cross-reference; when absent, look for it next to the test file (its extension replaced by .unit-test.md) and in each docs/<feature-id>-<kebab>/ folder whose checklist names the test file; when none is found, report checklist alignment as not verified.
  • target_file (optional) — the source under test, to verify coverage completeness; when absent, the source the test file loads the unit from.
  • language (optional) — the suite's language; when given, it wins over what the profile and the repository say.
  • severity_filter (optional) — critical | major | minor (default: all).

OUTPUT

A compliance report (English): the project profile it applied (a few lines), summary counts, overall verdict — PASS = 0 critical and 0 major (minors are listed, not counted against it); PASS WITH WARNINGS = 0 critical and ≥1 major; FAIL = ≥1 critical — each violation ([SEVERITY] Rule-ID, location, description, expected, found, fix), the rules not verified or not applicable with the cause of each, coverage analysis, and positive findings. When dispatched, the verdict is the signal the caller consumes.

Directory input: one report per test file — a checklist or any other file in the folder is not audited — then a summary: a row per file with its counts and verdict, and the folder's verdict, derived from the summed counts. Several places breaking the same rule in one file are one finding with every location listed.


EXECUTION STEPS (3 Phases)

Phase 1 — Structural Analysis

Build the project profile from GATES.md (and the repository, for its fallbacks), and read the project's rules file when it names one. Resolve the suite's language and read its language file; when the language has none, say so and go on with the generic rules. Inventory the groups, tests, hooks and helpers. Map checklist ↔ tests (if provided) and the source's public behaviors ↔ tests. Note every import, every double, where each double is put in place relative to the point the unit binds to the real thing, and every cleanup point. Note the file's path (which suite) and its language.

Phase 2 — Rule-by-Rule Validation

Check EVERY rule from ../unit-test-writer/references/unit-rules.md:

  • Isolation [CRITICAL] — I1 the real unit is exercised, never a copy or a stand-in declared in the test; I2 nothing real crosses the system boundary (database, network, filesystem, queue, cache, clock, randomness, hardware); I3 each double, and each global the unit reads while it loads, is in place before the unit binds to it — before the unit loads, where dependencies are resolved at load time (a double passed as an argument is in place when the unit is built); I4 a fresh double per test, and a fresh answer per call where an answer can be consumed only once.
  • Forbidden Practices [CRITICAL] — F1 production code created or changed; F2 real I/O; F3 a focused or skipped test, or a test with no assertion; F5 mutable state shared between tests; F6 another test framework's API.
  • Speed [CRITICAL] — P1 a raised timeout, a real timer or a sleep in a test, whatever it was meant for; a double that can never answer (I6).
  • Test language [CRITICAL] — S3 names, comments and identifiers in the profile's test language.
  • Project rules [as the project's file grades them; CRITICAL when it does not say] — every rule of the project's rules file, cited by its heading. With no rules file there is no such category: the conventions of existing tests are context for the other rules, never findings of their own.
  • Structure [MAJOR] — S1 the file sits where the suite's tests live, named as the profile says; S2 the suite's language and its idiom, as the language file states it; S4 arrange-act-assert, one behavior per test; S5 no dependence on another test or on order.
  • Assertions [MAJOR] — V1 behavior rather than implementation; V3 the clock and randomness controlled; V4 asynchronous and concurrent work waited to its end; V5 no expected value recomputed the way the unit computes it — the same formula, the same helper, or the unit's own output fed back.
  • Coverage [MAJOR] — V2 success, each error path and the boundaries of every public behavior; checklist alignment. A behavior the checklist records as not unit-testable — no seam (I8) is not missing when the claim holds: check it against the target and the language file's definition of a seam. Where the dependency does have a seam, the behavior is missing — a V2 finding that names I8.
  • Cleanup [MAJOR] — C1 doubles reset, timers restored, listeners removed, framework fixtures destroyed, globals put back.
  • Doubles [MINOR] — I5 a framework container started where passing doubles directly would isolate the unit; I6 a double whose shape differs from the real collaborator's without hanging the test; I7 a collaborator that is deterministic logic of the same codebase, with no I/O, replaced by a double.
  • Language anti-patterns [as the language file grades each] — every anti-pattern of the suite's language file, cited by its id. With no language file there is no such category.
  • Scope [MINOR] — F4 third-party code or an accessor with no logic under test.
  • Naming [MINOR] — N1 the group is the unit, and each test says what the unit does and under which condition.

Overlaps, counted once — the highest severity wins: real I/O is one I2 finding (F2 is the same breach); a real clock or real randomness is one I2 finding (V3 is the same breach); a sleep, a real timer or a raised timeout is one P1 finding (V3 and V4 are the same breach); a test that reads what another left behind is one F5 finding (S5 is the same breach); a test that never exercises the real unit is one I1 finding (the V1 and V2 gaps that follow from it are the same breach). A language anti-pattern that is the form a generic rule's breach takes is one finding, citing both ids. Several places breaking the same rule in one file are one finding with every location listed. A project rule broken by the same line is a finding of its own, cited by its heading.

What is not audited, and what has no subject: the execution rules (E1–E4) are the writer's; the validator runs nothing — no test and no project code; read-only git commands (status, log, show, diff) are allowed. F1 is checked against the commit or diff that adds the tests. A commit that adds production code along with them — a root commit that adds the whole repository, say — proves nothing either way: report F1 as not verified, never as a violation. With no commit and no diff, it is not verified too. Where the language keeps unit tests inside the source file, a commit or diff that is the writer's alone — tests and nothing else — is read line by line: a change confined to the test module is test code, and a changed line outside it is an F1 violation. One that also carries production changes proves nothing, as above. A rule with nothing to apply to — no double exists, so I3 to I6 have no subject; the unit takes its collaborators as arguments and reads nothing while it loads, so I3 has none — is reported as not applicable, with the cause.

Do not skip rules after finding criticals. State which were skipped and why.

Phase 3 — Compliance Report

Emit the full report per OUTPUT. Verdict is derived strictly from the counts.


RULES

Always:

  • Build the project profile from GATES.md, then validate against ../unit-test-writer/references/unit-rules.md, the suite's language file and the project's own rules file; check every rule.
  • Give exact line/block locations and a concrete fix per violation; report positives. Output in English.
  • Derive the verdict strictly from severity counts.

Never:

  • Modify any test or production file (read-only). Execute the tests. Mark PASS with any CRITICAL. Produce partial reports.
  • Judge a project by another project's locations, runner or mocking rules.

Edge Cases

  • Empty test file: CRITICAL. A test with no assertion: CRITICAL (F3).
  • Tests pass but break a rule: still flag — a passing test that imports a copy of the unit proves nothing.
  • A file of an integration, e2e or visual suite: out of scope — say so; do not validate it against these rules.
  • GATES.md has no test profile and the repository reveals no suite: report that the project profile cannot be built, and validate only the rules that do not depend on it, stating which were skipped.
  • The project's rules contradict a rule here: the project's wins; do not report the generic rule as violated.
  • The suite's language has no language file: validate against the generic rules alone, read in the language's own idiom, and say so in the profile lines of the report.
  • No checklist can be found: state that checklist alignment, and the notes the rules put there, were not verified. It is not a violation of the file.
  • Two test files for one source (S1): the finding goes on the file whose name does not follow the profile.
  • Directory input: one report per test file, then the summary with the folder's verdict, as OUTPUT describes.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.