a11y-fixes
Resolve axe-core accessibility violations reported by Vitest (test/a11y.ts), Playwright (.playwright/a11y.ts), or the code-audit-frontend agent's a11y bucket.…
Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
$ npx -y skills add gaia-react/gaia --skill tdd --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/tddContext preview
The summary Claude sees to decide when to auto-load this skill.
Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
name: tdd description: Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
Before writing the first red test, consult the reference for your stack:
Add a new `references/tests-{stack}.md` when adopting a new stack. The stack reference covers concrete patterns, test layers, mocking rules, and good/bad examples specific to that environment.
**Core principle**: tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
**Good tests** are integration-style, they exercise real code paths through public APIs and describe _what_ the system does, not _how_. A good test reads like a specification: "user submits a valid form and sees a success toast" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
**Bad tests** are coupled to implementation. They mock internal collaborators, spy on state setters, or assert on internal call signatures. The warning sign: your test breaks when you refactor, but behavior hasn't changed.
**DO NOT write all tests first, then all implementation.** This is "horizontal slicing", treating RED as "write all tests" and GREEN as "write all code."
Tests written in bulk test _imagined_ behavior, not _actual_ behavior. You outrun your headlights, committing to structure before understanding the implementation, producing tests insensitive to real changes.
**Correct approach**: vertical slices via tracer bullets. One test → one implementation → repeat.
WRONG (horizontal): RED: test1, test2, test3, test4, test5 GREEN: impl1, impl2, impl3, impl4, impl5 RIGHT (vertical): RED→GREEN: test1→impl1 RED→GREEN: test2→impl2 RED→GREEN: test3→impl3 ...
Before writing any code:
Ask: "What should the public interface look like? Which behaviors are most important to test?"
**You can't test everything.** Focus on critical paths and complex logic, not every edge case.
Write ONE test that confirms ONE thing end-to-end for this layer. `RED → GREEN`. The tracer bullet confirms the testing infrastructure wires up before adding real coverage.
For each remaining behavior: `RED → GREEN`. One test at a time. Only enough code to pass the current test. Don't anticipate future tests.
**Bound the green chase.** If a test won't pass after a few focused attempts, stop and reassess instead of thrashing the implementation: the test, the interface, or an assumption may be wrong. Surface the blocker rather than looping indefinitely to force green.
The deterministic surface (pure utils, service parsers, spec-derivable hooks) is RED-gated: a new test there commits only after a genuine failing-first run is observed at its current body.
**Author the test against the not-yet-written or stub implementation symbol.** Write the test for the behavior you are about to build, pointing at a symbol that does not exist yet (or exists only as a stub that returns the wrong value). Run it; it fails because the implementation is missing or incomplete. That failure is the honest RED: a real missing-implementation failure, not a manufactured one. Then write the implementation that turns it green.
RIGHT: test names parseAmount() → run → fails (parseAmount undefined / stub) → implement → green WRONG: implement parseAmount() → write the test → break parseAmount() to force red → restore it → green
**Never break working production code to force a red, then restore it.** That pattern relocates the theater into the implementation file: it is mechanically identical to the green-only theater the RED gate condemns. The content signal covers the test's comment-free content, so rewording a comment leaves a captured RED intact, while editing what the test itself executes invalidates it. The signal never covers the implementation, so this is a pattern the gate cannot catch: it is an authoring obligation, not an enforced one. The honest path is always to author the test against the absent or stub symbol, so the red comes for free from the missing implementation.
**Single-pass-author exemption.** When the implementation already exists in the same change with no prior failing observation (a single-pass author landing impl and test together), do NOT manufacture a red by breaking and restoring the impl. Author the test honestly against the existing behavior and route it to the worthiness audit, exactly as an emergent test is routed. A test that lands alongside its implementation with no prior failing observation is detectable, and a missed RED on it is caught late by the advisory audit, never by forcing theater up front.
After all tests pass, look for [refactor candidates](refactoring.md):
**Never refactor while RED.** Get to GREEN first.
After green, classify every touched source file and report the verdict. C
Claude is raw power. GAIA is order and focus. The foundation that keeps Claude-shipped code production-grade as your team scales. The React frontend is handled. You build the rest of your app on top. Every convention enforced in code.
Repo: gaia-react/gaia
Resolve axe-core accessibility violations reported by Vitest (test/a11y.ts), Playwright (.playwright/a11y.ts), or the code-audit-frontend agent's a11y bucket.…
Resolve specific ESLint errors and warnings that appear in this project. Use when fixing lint failures, ESLint reported issues, or autofix conflicts (e.g.…
File a new tech-debt GitHub issue for an out-of-scope code-review finding, building the dedup key, checking for an existing open or declined-closed match, and…
Generate a comprehensive GAIA session handoff document, accomplishments, decisions, current state, open questions, so context can be cleared or compacted…
Restore context from the most recent GAIA session handoff and suggest the next action. Trigger on `/gaia-pickup` or natural-language asks like "pick up where…
Diagnose React render performance by driving a micro-interaction, capturing real renders, and surfacing memo-defeating reference instability with a recommended…