Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Stack-agnostic test-driven development loop for a single Foreman issue. Implements one vertical slice with strict red-green-refactor (one test at a time, never horizontal slicing) using the foreman-test wrapper, saves completion evidence, then emits a machine-readable FOREMAN-SUMMARY block Foreman parses.
.claude/skills/visionforge-ou-foreman-tdd/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 270% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 186% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 63% | 0% |
(Adapted from mattpocock/skills tdd — see NOTICE. Made stack-agnostic: test, lint and typecheck commands are injected by Foreman from config.yaml, not hard-coded to npm/Husky. Removed interactive "confirm with the user / get user approval" steps — those become escalation triggers. Added the FOREMAN-SUMMARY output block.)
ISS-NNN.md) — its Goal, Acceptance criteria, Out ofscope, prd_refs, and its acceptance_check (a runnable check Foreman re-runs independently — your slice is not done until it passes). This is your slice definition.
test, lint, typecheck) — but you runtests through the foreman-test wrapper (see below), never the raw runner.
CONTEXT.md, relevant ADRs).runs/<id>/evidence/) you MUST populate beforeclaiming done.
You run headless in a git worktree on the issue's branch, cwd set to that worktree. Implement the slice and stop. Do not ask for confirmation.
Run tests with foreman-test (on your PATH) instead of the raw test runner:
foreman-test — full suite, quiet output (counts + failures only), full logon disk with greppable ERROR lines.
foreman-test --fast — a deterministic per-worker random subsample for cheapinner-loop runs. Use this while iterating; run the full foreman-test before you finish. Foreman re-runs the full suite itself regardless.
Wall-clock discipline: the wrapper prints elapsed time. Spend at most ~1 turn in 3 re-running tests; the rest goes to making changes. Don't loop on the runner.
verification.json, any issue file, and the canonical *.check/ artifacts are Foreman's. A worktree hook will block (and surface) any attempt to write them — do not try. Foreman decides "done", not you.
Tests verify behavior through public interfaces, not implementation details. Good tests are integration-style: they exercise real code paths through public APIs and read like a specification ("user can checkout with valid cart"). They survive refactors. Bad tests mock internal collaborators, assert on call counts/order, or verify through external means. See tests.md.
DO NOT write all tests first, then all implementation. That produces tests of imagined behavior. Work vertically: one test → its implementation → repeat. Each test responds to what you learned from the previous cycle.
WRONG (horizontal): RED: test1..test5 then GREEN: impl1..impl5
RIGHT (vertical): RED→GREEN: test1→impl1 ; test2→impl2 ; test3→impl3 ; ...Derive the behaviors to test from the issue's Acceptance criteria. Use the project's domain glossary for test and interface names. Identify the public interface/seam for the slice and design it for testability (small interface, deep implementation). List the behaviors — not implementation steps. You set this plan yourself; there is no user to approve it. If a criterion is ambiguous or contradicts an ADR or the codebase such that you cannot proceed safely, STOP and emit a FOREMAN-SUMMARY with escalate: true and the specific question (Foreman routes it to the human attention queue).
Write ONE test for the first behavior → run the test command → it fails (RED). Write the minimal code to pass → run again → it passes (GREEN). This proves the path end-to-end.
For each remaining acceptance criterion: RED (one new test, fails) → GREEN (minimal code, passes). One test at a time. Only enough code to pass the current test. Don't anticipate future tests. Keep tests on observable behavior.
After all tests pass: extract duplication, deepen modules, apply SOLID where natural, run the test command after each refactor step. Never refactor while RED.
Run the full foreman-test, then lint, then typecheck (whichever exist) and capture each command's pass/fail and a short output tail. Confirm the issue's acceptance_check passes.
Completion contract (required): before claiming done, save evidence artifacts proving you observed success into the evidence directory Foreman gave you (runs/<id>/evidence/) — at minimum the test log, plus command outputs (and a screenshot for UI work via the configured e2e tooling). List each saved artifact in the FOREMAN-SUMMARY evidence array. A "complete" claim with missing or empty evidence is rejected and counts as a failed attempt — Foreman validates the evidence on disk and re-runs every command itself; it does not trust claims.
End every run with exactly one fenced block tagged json whose content is a single JSON object on the schema below. Nothing after it.
`md
{ "schema": "foreman-summary/v1", "issue_id": "ISS-001", "files_touched": "path/a", "path/b"], "tests_added": "describe/it name or test function name", "..."], "commands": { "test": {"ran": true, "passed": true, "output_tail": "...last lines..."}, "lint": {"ran": true, "passed": true, "output_tail": "..."}, "typecheck": {"ran": false, "passed": null, "output_tail": "not configured"} }, "evidence": "test.log", "acceptance.log"], "open_concerns": "anything you are unsure about"], "escalate": false, "escalation_question": "", "request_more_turns": 0 }
evidence lists the artifacts you saved under runs/<id>/evidence/. It must benon-empty for a completion claim; Foreman rejects an empty/unbacked claim.
escalate: true + a non-empty escalation_question means you could not finishsafely and need a human decision; set it instead of guessing.
request_more_turns: N (a small positive integer) means you are making realprogress but cannot finish this slice within your turn budget. Set it INSTEAD of letting Foreman cut you off, and do not also set escalate. Write your progress.md handoff first. Foreman may grant a bounded extension and resume this same session so you continue where you left off. Use escalate (not this) for genuine blockers; leave this 0 when you finish normally.
commands[*].passed is your honest result; Foreman verifies independently.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 5,008 | 4,855 | -3% | 1 | 1 | 0% | 254 | 1,979 | +679% | 0 | 0 | — |
case-02 | fail→fail | 5,471 | 5,481 | +0% | 1 | 1 | 0% | 292 | 1,977 | +577% | 0 | 0 | — |
case-03 | fail→fail | 4,682 | 4,877 | +4% | 1 | 1 | 0% | 185 | 1,921 | +938% | 0 | 0 | — |
case-04 | pass→pass | 9,773 | 2,905 | -70% | 1 | 1 | 0% | 1,507 | 2,190 | +45% | 0 | 0 | — |
case-05 | fail→pass | 3,809 | 2,369 | -38% | 1 | 1 | 0% | 560 | 2,070 | +270% | 0 | 0 | — |
case-06 | fail→pass | 15,584 | 7,452 | -52% | 1 | 1 | 0% | 2,194 | 2,825 | +29% | 0 | 0 | — |
case-07 | fail→pass | 5,083 | 2,904 | -43% | 1 | 1 | 0% | 756 | 2,159 | +186% | 0 | 0 | — |
case-08 | fail→pass | 9,939 | 6,080 | -39% | 1 | 1 | 0% | 1,693 | 2,615 | +54% | 0 | 0 | — |
case-09 | pass→pass | 5,927 | 5,141 | -13% | 1 | 1 | 0% | 934 | 2,486 | +166% | 0 | 0 | — |
case-10 | fail→pass | 9,568 | 4,179 | -56% | 1 | 1 | 0% | 1,494 | 2,441 | +63% | 0 | 0 | — |
case-11 | fail→fail | 8,874 | 1,867 | -79% | 1 | 1 | 0% | 1,356 | 1,988 | +47% | 0 | 0 | — |
case-12 | pass→pass | 11,440 | 6,284 | -45% | 1 | 1 | 0% | 1,867 | 2,735 | +46% | 0 | 0 | — |
case-13 | fail→fail | 5,235 | 2,237 | -57% | 1 | 1 | 0% | 770 | 1,999 | +160% | 0 | 0 | — |
case-22 | pass→fail | 16,990 | 3,558 | -79% | 1 | 1 | 0% | 2,543 | 1,856 | -27% | 0 | 0 | — |
case-14 | fail→pass | 10,707 | 4,302 | -60% | 1 | 1 | 0% | 1,570 | 2,466 | +57% | 0 | 0 | — |
case-15 | pass→pass | 14,425 | 3,282 | -77% | 1 | 1 | 0% | 2,209 | 2,173 | -2% | 0 | 0 | — |
case-16 | pass→pass | 3,046 | 3,590 | +18% | 1 | 1 | 0% | 538 | 2,284 | +325% | 0 | 0 | — |
case-17 | fail→fail | 4,853 | 5,512 | +14% | 1 | 1 | 0% | 631 | 2,623 | +316% | 0 | 0 | — |
case-18 | fail→pass | 10,689 | 3,244 | -70% | 1 | 1 | 0% | 1,549 | 2,274 | +47% | 0 | 0 | — |
case-19 | pass→fail | 4,948 | 2,268 | -54% | 1 | 1 | 0% | 786 | 2,049 | +161% | 0 | 0 | — |
case-20 | pass→pass | 9,504 | 10,053 | +6% | 1 | 1 | 0% | 1,645 | 3,655 | +122% | 0 | 0 | — |
case-21 | pass→pass | 15,389 | 22,369 | +45% | 1 | 1 | 0% | 2,099 | 4,702 | +124% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +23 percentage points is the difference between those two pass rates over the 18 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.