Testability Canary (Decoupling & Mockability Audit)
Audit code to ensure it is decoupled, modular, and easy to cover with automated tests.
Auditing Categories
- Hardcoded Constructors — instantiating deps inside classes (
new DatabaseClient()) instead of injecting via constructor/factory (prevents mocking). - SRP Violations — a class or method doing too many distinct duties (e.g. a service that also parses JSON and formats UI).
- Static Dependencies — reliance on global static methods or Singletons that make test isolation impossible.
- Time & Environment Coupling — direct
DateTime.Now,fs, orprocess.envcalls without an abstraction layer (fragile time/path-sensitive tests). - Private Logic Gaps — complex business logic hidden in private methods that can't be tested directly (extract to testable helpers).
Per-stack patterns and the mock-strategy vocabulary: read references/checks.md before scanning.
Fix mode (choice-gated)
In Agent Context, after the report, present via ask_question:
- Apply safe refactoring: extract hardcoded initializations into constructor params (DI) + add interface definitions. Each fix: checkpoint (git stash/commit in a git repo; else copy the file aside — never assume git) → apply → build + tests → auto-revert if newly red.
- Let me pick: user selects specific refactoring moves.
- Report only: exit unchanged.
Grants & denials (CLASSIFY-BLOCK)
| class | step it powers | grant | on denial |
|---|---|---|---|
| read | scan coupling/DI surfaces for the categories above | Read·Grep·Glob |
refuse that file, name it — never a clean bill |
| write | Fix mode's safe-refactor apply, incl. checkpoint → build+tests → auto-revert if newly red | Edit·Bash (checkpoint/build/revert need exec) |
report the fix as NOT applied AND the checkpoint/revert as NOT available, never claim done |
Output
| file:line | coupling point | severity | finding | mock strategy |
Severity: CRITICAL (un-mockable external write/network call) · HIGH (SRP violation blocking unit testing) · MEDIUM (time/env coupling) · LOW (minor static dependency)