agentleFS
imMamdouhaboammarimMamdouhaboammar/get-fable/skills/fable-tdd/SKILL.md

fable-tdd

Skill6 starsChanged 3 months agoMITView on GitHub

Drive testable behavior changes and bug fixes through disciplined red-green-refactor cycles with observable regression tests. Use when implementing new features with unit/integration tests, fixing reproducible bugs, modifying business logic, or writing test-first behavior contracts — even if the user does not explicitly say \"fable-tdd\" (e.g. \"fix this bug test-first\", \"write a test and make it pass\", \"add this feature with tests\", \"TDD this logic\"). Do NOT use for broad exploratory prototyping without clear assertions (use fable-discover or fable-plan) or for post-implementation reviews (use fable-review).

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. About 0 are common, 14 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈14

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use the lowest test level that proves the real behavior without mocking away the thing under test.

    line 69
  2. Distinctive:

    Before RED, confirm the chosen test actually executes the relevant path.

    line 85
  3. Distinctive:

    If you cannot answer #1, the test is probably weak.

    line 104
  4. Distinctive:

    Write the smallest test that captures the behavior contract and run it.

    line 107
  5. Distinctive:

    If the failure reason is wrong, repair the test/harness and repeat RED.

    line 115
  6. Distinctive:

    Run the focused test until GREEN.

    line 127
  7. Distinctive:

    Before refactor, probe the closest failure surfaces appropriate to the change:

    line 130
  8. Distinctive:

    Add tests only when they protect a meaningful contract.

    line 139
  9. Distinctive:

    Test passes before production change → it does not prove the requested gap.

    line 155
  10. Distinctive:

    Test errors before assertion → fix harness/test, not production.

    line 156
  11. Distinctive:

    Test expectation conflicts with current agreed product contract → do not force implementation to an obsolete test.

    line 162
  12. Distinctive:

    No production behavior mutation before a valid RED for testable changes.

    line 166
  13. Distinctive:

    Test passes but does not cross the real failure boundary, often because a mock or stale artifact bypasses it.

    line 178
  14. Distinctive:

    No narrow seam exists. Characterize at a stable boundary, then introduce the smallest seam supported by the test.

    line 184

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Fable TDD

Prove the behavior is missing or broken before changing production code, then make the smallest change that satisfies the right test at the right level.

Mission

TDD is not "write any failing test first." The red state must demonstrate the intended behavior gap through a trustworthy harness. A syntax error, broken fixture, stale build, or mock-only expectation does not earn the right to change production code.

The Skill optimizes for three things:

  • causal confidence: the test fails because the behavior is wrong;
  • minimal intervention: implementation changes only what the behavior requires;
  • durable regression proof: the test would catch the bug if it returned.

Activate When

  • fixing a reproducible bug or regression;
  • adding behavior with a stable enough contract to assert;
  • changing validation, state transitions, calculations, API behavior, persistence, or integration semantics;
  • refactoring where an invariant needs executable characterization first.

Do Not Activate When

  • the behavior cannot yet be located or reproduced (fable-discover);
  • the main uncertainty is external API semantics (fable-research);
  • the change is non-executable docs/metadata with no meaningful behavior test (fable-execute);
  • the required test harness is itself broken or executing stale artifacts (fable-recover).

Change Classification

Classify the behavior before choosing a test.

ClassPreferred proof
Pure/domain logicfocused unit/property test
Boundary validation/error mappingunit or contract test at boundary
Cross-module interactionintegration test through the changed contract
Database/queue/cache behaviorintegration test with realistic boundary where feasible
HTTP/CLI/public APIcontract/integration test at public entry point
UI user flowcomponent/integration first; E2E for high-value cross-boundary behavior
Concurrency/timingdeterministic coordination test, not sleep-and-hope
Legacy behavior with poor seamscharacterization test at nearest stable boundary
Refactor/no intended behavior changecharacterization/invariant tests before movement

Use the lowest test level that proves the real behavior without mocking away the thing under test.

Protocol

Stage 1 — Write the behavior contract

State:

  • initial state/input;
  • trigger/action;
  • expected observable result;
  • relevant side effects;
  • error/boundary behavior;
  • invariant that must remain true.

For a bug, capture the concrete reproduction separately from the proposed implementation.

Stage 2 — Validate the harness

Before RED, confirm the chosen test actually executes the relevant path.

Check when applicable:

  • source vs built artifact;
  • test discovery/config;
  • fixture realism;
  • feature flags/env;
  • mock boundaries;
  • asynchronous completion;
  • cleanup/isolation;
  • whether the assertion observes public behavior rather than an internal call count.

Stage 3 — Choose the test level

Ask:

  1. What production change would make this test fail again?
  2. Does the test cross the contract where the bug actually lives?
  3. Have I mocked the suspected failure away?
  4. Can a narrower test prove the same user-visible behavior more deterministically?

If you cannot answer #1, the test is probably weak.

Stage 4 — RED

Write the smallest test that captures the behavior contract and run it.

RED is valid only if:

  • test executes;
  • failure is deterministic enough to reason about;
  • failure message/state matches the expected missing/broken behavior;
  • it is not failing because of setup, syntax, import, environment, stale artifact, or unrelated test pollution.

If the failure reason is wrong, repair the test/harness and repeat RED. Do not touch production code yet.

Stage 5 — Minimal GREEN

Change the smallest production surface that can satisfy the valid RED.

Do not:

  • redesign adjacent APIs;
  • add speculative flexibility;
  • refactor unrelated code;
  • weaken the assertion;
  • replace real behavior with a mock to reach green.

Run the focused test until GREEN.

Stage 6 — Adjacent falsification

Before refactor, probe the closest failure surfaces appropriate to the change:

  • boundaries/empty/invalid input;
  • error path;
  • state transition ordering;
  • idempotency/retry;
  • concurrency/race;
  • compatibility with prior format/API;
  • persistence/transaction behavior.

Add tests only when they protect a meaningful contract; do not inflate count mechanically.

Stage 7 — Refactor under green

Now improve structure if needed. Refactor in small steps and rerun the affected tests after each meaningful mutation.

Stage 8 — Fresh handoff

Record final mutation and hand off to fable-verify with:

  • behavior contract;
  • exact RED evidence/reason;
  • GREEN command/result;
  • tests added/changed;
  • production surfaces changed;
  • adjacent cases probed;
  • residual risks not covered by the focused test.

Decision Rules

  • Test passes before production change → it does not prove the requested gap; redesign the test or confirm behavior already exists.
  • Test errors before assertion → fix harness/test, not production.
  • Bug is nondeterministic → first control or instrument the nondeterminism; repeated random reruns are not a reliable RED.
  • Concurrency bug → prefer barriers/latches/fake clocks/deterministic scheduling over arbitrary sleeps.
  • Legacy code has no unit seam → test the nearest stable public boundary before introducing a seam; do not perform a broad refactor just to make unit testing aesthetically pure.
  • External dependency cannot be exercised locally → use a contract/fake only after establishing what behavior the fake must preserve from primary evidence.
  • User asks to "just patch it" → if executable behavior is changing, preserve RED discipline unless the absence of a viable harness is explicit and accepted.
  • Test expectation conflicts with current agreed product contract → do not force implementation to an obsolete test; resolve the contract first.
  • A test only asserts that a mock was called → add observable outcome/state evidence unless the call itself is the public contract.

Invariants

  • No production behavior mutation before a valid RED for testable changes.
  • RED and GREEN refer to the same behavior contract.
  • Tests are not weakened to make implementation pass.
  • The suspected failure mechanism is not mocked away.
  • Final GREEN is fresh after the last relevant mutation.
  • Refactoring does not add behavior outside the accepted card.

Failure Taxonomy

Wrong RED

Failure comes from syntax/import/setup/fixture/environment rather than target behavior. Repair harness first.

False GREEN

Test passes but does not cross the real failure boundary, often because a mock or stale artifact bypasses it. Strengthen/reposition the test.

Flaky RED/GREEN

Outcome changes without relevant code mutation. Identify nondeterminism before treating either state as evidence.

Untestable legacy surface

No narrow seam exists. Characterize at a stable boundary, then introduce the smallest seam supported by the test.

Contract ambiguity

Expected behavior itself is disputed/unclear. Return to planning/research rather than encoding a guess as a test.

Implementation loop

Valid RED exists but two materially similar fixes fail. Stop editing and route to fable-recover with the RED, attempts, and observed failure differences.

Anti-Patterns

  • writing implementation, then backfilling a test that immediately passes;
  • accepting any failure as RED;
  • changing expected output to match current implementation;
  • asserting only mock interactions when user-visible state can be asserted;
  • using sleeps to "test" a race;
  • building an elaborate test abstraction before proving one behavior;
  • broad legacy refactor before characterization;
  • forcing unit tests where only an integration boundary can prove the behavior;
  • skipping fresh GREEN after refactor;
  • equating coverage percentage with regression proof.

Evidence Packet

Behavior contract:
Test level + why:
RED command/result + expected failure reason:
Production mutation:
GREEN command/result:
Adjacent cases probed:
Refactor mutations:
Final fresh GREEN:
Residual risk / verify next:

Completion Criteria

TDD completes when:

  • the behavior gap was demonstrated by a valid RED;
  • production code changed only after that RED;
  • focused GREEN is observed for the same contract;
  • meaningful adjacent failure surfaces were considered;
  • final tests are fresh after refactor/last mutation;
  • fable-verify receives enough evidence to independently falsify the result.

Progressive Resources

  • Deep strategy: references/test-strategy-and-hard-cases.md
  • Existing cycle reference: references/red-green-refactor.md
  • Example: examples/failing-test-first.md

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.