Enforces failing-first tests for Rust projects via git history.
tdd-ratchet wraps cargo nextest and tracks
per-test states in a trusted .test-status.json ledger. It enforces
that every new test must fail before it can pass - verified by
inspecting git history. No shortcuts.
Every test goes through exactly two states. Each transition is a separate commit.
A test that passes on its first appearance is rejected. A passing test that starts failing is a regression. A tracked test that disappears is rejected.
# 1. Write a failing test
# 2. Run locally, then push the red test
cargo ratchet
git add tests src && git commit -m "test: describe expected behavior"
git push
# Wait for the trusted workflow to record pending
# 3. Implement the feature
# 4. Run and push - the workflow records passing
cargo ratchet
git add src && git commit -m "feat: implement the behavior"
git push
# Linux x86_64, latest release
curl -Lo ~/.local/bin/cargo-ratchet https://tdd-ratchet.maxeonyx.com/releases/cargo-ratchet-x86_64-linux
chmod +x ~/.local/bin/cargo-ratchet
Alternative (build from source; the crates.io tdd-ratchet is an old 0.1.0):
cargo install --git https://github.com/maxeonyx/tdd-ratchet-rs --locked
Then initialize:
cargo ratchet --init
The .test-status.json file is committed to your repo by the
trusted ledger workflow. Developers do not hand-edit it. It maps full
nextest test names to their expected state:
{
"$schema": "https://tdd-ratchet.maxeonyx.com/schema/test-status.v1.json",
"tests": {
"my-crate::tests$it_does_the_thing": "passing",
"my-crate::tests$planned_feature": "pending"
}
}
JSON Schema -
add "$schema" to your status file for editor validation.
Put deliberate renames or removals in
.tdd-ratchet.json. The workflow validates those instructions
before its isolated writer records the resulting ledger.
The ratchet checks three things on every run:
pending before passing. No test can skip the failing step.cargo test run directly (outside the ratchet) fails with instructions.