SaferSkills independently audited TDD (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Practice strict Test-Driven Development in the style of t-wada / Kent Beck. The goal is 動作するきれいなコード — clean code that works, grown one small verified step at a time.
No production code without a failing test you have seen fail. No exceptions.
if [ -f pnpm-lock.yaml ]; then echo pnpm; elif [ -f yarn.lock ]; then echo yarn; elif [ -f bun.lock ] || [ -f bun.lockb ]; then echo bun; elif [ -f package-lock.json ]; then echo npm; else echo "npm (no lockfile found)"; finode -p "const p = require('./package.json'); const v = { ...p.dependencies, ...p.devDependencies }.vitest; v ? v : 'NOT found in package.json'" 2>/dev/null || echo "package.json not found"found=$(ls vitest.config.* vitest.workspace.* vite.config.* 2>/dev/null); echo "${found:-none found — check package.json or ask the user}"grep -qsE "globals[\"']? *: *true" vitest.config.* vite.config.* 2>/dev/null && echo "enabled — use describe/it/expect/vi without imports" || echo "not detected — import { describe, it, expect, vi } from 'vitest'"node -p "Object.entries(require('./package.json').scripts ?? {}).filter(([k]) => k.includes('test')).map(([k, v]) => k + ': ' + v).join(' | ') || 'none'" 2>/dev/null || echo "package.json not found"If anything above is missing or contradicts the repository, read package.json and the Vitest config yourself before running tests. Never guess commands.
| Task | TDD required? |
|---|---|
| New feature / new behavior | Yes |
| Bug fix | Yes — failing regression test first |
| Refactoring logic | Yes — green tests before, during, after |
| Changing untested legacy code | Yes — characterization tests first (see below) |
| Comments, docs, formatting only | No |
| Pure type declarations with no runtime effect | No — consider type tests (expectTypeOf) |
| Config / CI / dependency bumps | No — but run the full suite afterwards |
If the user explicitly opts out of TDD, note the tradeoff in one sentence and follow their instruction. Otherwise this skill is binding.
vitest (or a test script without run) can block the session forever. Always use vitest run …..skip without a written reason. If a test is wrong, fix it and say why.it('returns 0 for an empty cart') — never after the implementation.--allowOnly=false).探索 Explore → Plan (test list) → 🔴 Red → 🟢 Green → 🔵 Refactor → next item … → DoneRead the relevant code, types, and existing tests before planning. If an unfamiliar API needs investigation, a throwaway spike is allowed — but spike code must be deleted or rebuilt test-first before integration. Never promote untested spike code to production.
it.todo(…) placeholders in the test file and mirror it in your task tracker.describe('calculateTotal', () => {
it.todo('returns 0 for an empty cart');
it.todo('sums item prices');
it.todo('applies percentage discount');
it.todo('never returns a negative total');
});expect line, then work backwards to the setup. Expected values are concrete literals — never computed with the logic you are about to implement.npx vitest run src/cart.test.tsnpx vitest run -t "applies percentage discount"Pick the smallest workable strategy:
| Strategy | When | How |
|---|---|---|
| 仮実装 (Fake It) | Unsure how to implement | Return a hard-coded constant; generalize later |
| 三角測量 (Triangulation) | The fake must become real | Add a second test with different values the constant cannot satisfy, then generalize |
| 明白な実装 (Obvious Implementation) | Implementation is trivial and certain | Just write it — if it does not go green immediately, fall back to smaller steps |
Run the affected tests. Gate: the new test passes and nothing else broke. Speed to green beats elegance — sins committed here are repaid in Refactor.
90 appearing in both is the signal to generalize a fake).Then return to the list and pick the next item.
it.todo (tell the user which)npx vitest run.only; every .skip carries a reason commenttsc --noEmit or the project's script); lint passes if configuredit.skip + a reason comment + a list item, and report it. Never delete it.Report each cycle compactly so the user can follow along:
🔴 applies percentage discount — fails as expected (expected 90, received 100)
🟢 pass (7 tests, 112ms) — fake-it with constant
🔵 generalized via triangulation; extracted applyDiscount() — all greenBefore changing behavior in code that has no tests: pin the current behavior with characterization tests — assert what the code actually does today, even if it looks wrong, and report oddities to the user instead of silently "fixing" them. Once green, proceed with the normal cycle.
it.each, fixtures, assertion stylevi.* usage: mock boundaries, not your own logic~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.