ijfw-agents-md
Maintain canonical AGENTS.md (open spec). Trigger: 'agents.md', 'update AGENTS.md', or auto-fired by ijfw-team after agent generation.
RED-GREEN-REFACTOR enforcement. Use when implementing a feature or bugfix before writing implementation code. Trigger: tdd, test first, red green refactor, /ijfw-tdd
$ npx -y skills add FerroxLabs/ijfw --skill ijfw-tdd --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/ijfw-tddContext preview
The summary Claude sees to decide when to auto-load this skill.
RED-GREEN-REFACTOR enforcement. Use when implementing a feature or bugfix before writing implementation code. Trigger: tdd, test first, red green refactor, /ijfw-tdd
name: ijfw-tdd description: "RED-GREEN-REFACTOR enforcement. Use when implementing a feature or bugfix before writing implementation code. Trigger: tdd, test first, red green refactor, /ijfw-tdd" since: "1.5.0"
Write the test first. Watch it fail for the right reason. Write the minimum code to make it pass. Then improve structure without changing behavior.
**Iron law:** No production code without a failing test first. If you wrote code before the test, delete it. Implement fresh from the test.
This skill enforces three distinct moves. Each move has a green light that you must hit before advancing. Skipping a green light is not "pragmatic" -- it is the bug.
---
Write ONE minimal test for ONE behavior. Use a descriptive name. Use real code (no mocks unless unavoidable).
Before running the test, write down the failure message you EXPECT to see. Example: "AssertionError: expected 'Email required', got undefined" or "AttributeError: module has no attribute 'retryOperation'".
Then run it:
npm test path/to/test.ts # or pytest, cargo test, go test, etc.
Paste the actual failure into your scratch. Compare against what you predicted.
**Green light to advance:** the test FAILS, and the failure message is the one you predicted (an assertion failure on the intended behavior, or a "missing symbol" error if the function does not exist yet).
**Red flags that block advancing:**
---
Write the simplest implementation that turns the failing test green. No extra parameters. No "while I am here" cleanup. No anticipating tomorrow's tests. YAGNI.
Run the test. Paste the pass output. Run the full suite -- nothing else may regress.
**Green light to advance:** target test passes, full suite passes, output is pristine (no warnings, no stack-trace noise, no skipped tests you forgot about).
**Red flags that block advancing:**
---
Now and only now: rename, extract helpers, remove duplication, tighten types, collapse branches. The behavior must stay identical.
Run the FULL test suite after each meaningful change. Not at the end -- after each change. If you cannot remember which change broke green, you waited too long.
**Green light to advance to the next test:** every refactor kept the suite green. No new behavior was added under the cover of "cleanup."
**Red flag:** you find yourself wanting to add a feature mid-refactor. Stop. Commit the refactor. Start a new RED test for the new feature.
---
1. **Testing the mock, not the code.** Asserting `screen.getByTestId('sidebar-mock')` proves the mock loaded, not that the component works. The test passes for the wrong reason and gives false confidence. 2. **Tautological assertion.** `expect(result).toBe(result)` or `expect(fn()).toEqual(fn())`. Always green, proves nothing, exists only to push coverage numbers. 3. **Coverage-driven test that asserts nothing.** Calls the function, never checks the return value. The line counter goes up; the bug count does too. 4. **Skipping RED because "I know what it will fail on."** You don't. Half the time the test passes immediately (you tested the wrong thing) or errors on a typo (you tested nothing). Watching it fail is the only proof the test can ever fail. 5. **Test-only methods on production classes.** A `destroy()` that exists "for tests" is production API that real callers will eventually invoke. Put cleanup helpers in test utilities. 6. **Incomplete mocks.** Mocking only the fields your test reads hides the structural contract. Downstream code that consumes other fields fails silently. Mirror the real shape completely or do not mock at all.
---
TDD is not a software-only discipline. It applies anywhere you have a falsifiable claim about what "done" means.
In every domain, the move is the same: write the falsifiable claim FIRST, watch reality fail to meet it, then build until the check holds.
---
| Problem | Move | |---------|------| | Don't know how to test it | Write the wished-for API. Write the assertion. Ask for help. | | Test feels too complicated | The design is too complicated. Simplify the interface. | | Must mock everything | Code is too coupled. Use dependency injection. | | Test setup is huge | Extract helpers. Still huge? The design is wrong. |
Production artifact exists -- a function, a
IJFW — It Just F*cking Works. Ferrox Labs' local-first infrastructure for AI coding agents: shared memory, smart routing, multi-AI cross-audits, disciplined workflow.
Repo: FerroxLabs/ijfw
Maintain canonical AGENTS.md (open spec). Trigger: 'agents.md', 'update AGENTS.md', or auto-fired by ijfw-team after agent generation.
Session-end auto-extraction of lessons, errors, fixes, and user feedback into structured memory. Fires at session end. Requires consent on first run.
Terse conventional commits. Trigger: commit, git commit, /ijfw-commit
Use when a milestone is shipping and you need to archive its artifacts, generate a summary, and seed the next milestone. Trigger: 'milestone complete', 'ship…
Compress memory/context files into terse form. Trigger: /compress, compress file
Use when the user says: 'compute', 'crunch this', 'analyze logs', 'aggregate the data', 'run a script', 'dedupe', 'count by', 'top N', or any data-shaping ask.…