Skip to main content
Reference — generated from the toolkit

Source of truth: toolkit/skills/characterisation-tests/spec.md. Edit it there; this page is regenerated on build.

Skill: characterisation-tests

  • Owner: AI + Test
  • Version: 0.1.0
  • Lifecycle: draft
  • Phase: cross-cutting (STOP + Build)

Trigger

Before touching legacy code, pin its current behaviour so remediation and rebuilds refactor without silent regressions. The fastest way to raise the test floor on an untested product (Feathers' legacy-code technique).

Inputs → outputs

  • Inputs: a legacy module/service with little or no test coverage.
  • Outputs: characterisation tests that assert the code's existing behaviour (whatever it currently does), so any change that alters behaviour is caught.

Procedure

  1. Identify seams and observable behaviour.
  2. Generate tests that capture current outputs for representative and boundary inputs.
  3. Flag behaviours that look like bugs — but pin them as-is and record the question; do not "fix" during characterisation.
  4. Wire into CI so the legacy behaviour is protected before refactoring starts.

Guardrails & permissions

  • Tests assert what is, not what should be — correctness questions go to a human/SME, they are not silently corrected.
  • Standard agent guardrails; no production access.

Failure modes

  • Pinning a bug as correct behaviour (mitigated: suspicious behaviours are flagged for human review, not hidden).
  • Over-fitting to incidental output (mitigated: focus on contract-level behaviour).

Golden scenarios

ScenarioInputExpected outputPass criterion
Untested pure functionfixture moduletests pinning current outputs incl. boundariesmutation score on the module
Behaviour-changing refactorpinned module + refactorrefactor that changes behaviour fails a testcatches the regression