Verify changes
Run after any code change — most importantly one implemented by a separate session/agent — before calling it done. Two questions: did the change land cleanly, and is it actually tested. Report findings; never silently fix — the user decides.
1. Scope the change
Establish exactly what changed before judging it: git status --short + git diff for the working
tree, and — if the work was already committed — git log --oneline back to the session's base plus
git show --stat <sha>. List every changed/added source file and every changed/added test
file. A source change with no matching test change is the first thing to flag.
2. Type-check — baseline-aware
Run the repo's real type-checker (e.g. npx tsc --noEmit, mypy, go vet — whatever the project
uses). Many repos carry a pre-existing error baseline — do NOT report the baseline. Isolate
errors in the changed files only. If unsure whether an error is new, git stash the change,
re-run, and diff. The bar is zero new errors in changed files. Line-number shifts push errors
around in unchanged files without adding any — strip line numbers before diffing if the raw count
moved.
3. Tests — run the real suite
Find the test command in the project's manifest (package.json, Makefile, pyproject.toml,
etc.) — don't assume npm test. Honor any multi-environment matrix the project defines: if the
suite is meant to run under more than one configuration (multiple timezones, locales, runtimes, or
DB backends), every configured run must pass — a single run proves nothing. If there is a separate
locally runnable integration/DB-coupled suite for the area you changed, run it too.
4. Were tests added/modified correctly?
Passing is necessary, not sufficient — judge adequacy:
- Coverage of the change: every new/changed function or branch has a test that exercises it, not just adjacent code. New pure helpers especially.
- Would it fail without the change? If an assertion would still pass against the old code, it doesn't guard the change. Pin the new behavior precisely — exact values, not "truthy".
- Edge/throw paths: error cases, boundaries, empty inputs, and every documented invariant (a sentinel carried verbatim, an amount capped, a body that must serialize byte-identically) have explicit assertions.
- Behavior-preserving refactors: where the change claims "byte-identical" / "no behavior change", confirm a test or a direct diff actually proves it — don't take the claim on faith.
- Right layer: logic is tested at the pure/testable seam, not through a mock-heavy integration path that tests the mocks.
5. Report
Summarize: files changed, type-check result (new errors: expected 0), the test result (all configured runs), and a per-change verdict on test adequacy with specific gaps named. Everything missing is a finding for the user to decide on — do not fix it silently.