Quick Answer: The ub-mode agent skill is a single
SKILL.mdfile that tells AI coding agents to follow disciplined engineering practices: work through a defined set of principles, test behavior, and check every change with deterministic quality gates. Those gates are Crapper (CRAP score and complexity), Dryer (duplication), and Mutator (mutation testing). Install it by copyingSKILL.mdinto your agent's skills directory.
Ask most AI coding agents for a feature and you'll get working code fast. You'll also get extra abstractions, thin tests, and the same validation logic pasted into three places. Robert C. Martin's ub-mode repository takes a direct approach to this problem. It packages a working discipline as an agent skill and pairs it with tools that measure whether the discipline was followed. Here's what it asks for, where it's strict, and where it can fall short.
What ub-mode Actually Asks an Agent to Do
The README describes ub-mode in three phases. It's loosely derived from poteto's rules, and it trims them down to a set that can be enforced.
- First Make it Work. This phase covers the Laziness Protocol, TDD, "Attack the Premise," "Subtract Before You Add," and architecture rules such as boundary discipline and making operations idempotent.
- Then Make it Right. This phase covers fixing root causes, sequencing work into verifiable units, testing behavior rather than implementation, and running the quality gates.
- Practice. This phase covers keeping a log, guarding the context window, cleaning up worktrees, and committing in small, ordered steps.
The phase order matters. The agent is told to get something working before polishing it, which avoids the trap of gold-plating a design that never ran. Most agent workflows skip the "make it right" step entirely, so ub-mode's insistence on it is the part worth paying attention to.
One caveat: this article is based on the README. I haven't audited every rule in SKILL.md, so check the file itself before relying on specific wording.
Why the CRAP Score Threshold Is Stricter Than It Looks
ub-mode requires every function to have a CRAP score under 10. CRAP, introduced by Alberto Savoia and Bob Evans in 2007, combines cyclomatic complexity with test coverage. The standard formula is:
CRAP = complexity² × (1 − coverage)³ + complexity
Run a few numbers and the threshold starts to make sense. A function with complexity 3 and no tests scores 3² + 3 = 12, which fails. Add coverage of just 10 percent and it drops to about 9.56, which passes. A complexity-5 function with 80 percent coverage scores about 5.2, comfortably under the line.
Here's the counter-intuitive part. Because the formula ends with + complexity, a function with complexity 10 can never score below 10, even with 100 percent coverage. The threshold effectively caps complexity at 9. Most teams that adopt CRAP treat it as a coverage target. ub-mode treats it as a complexity ceiling as well, and that forces the agent to split functions instead of testing its way out of a messy one.
The README's "< 10" wording is what Crapper enforces. Confirm the exact semantics against the Crapper repository before wiring it into a build.
Coverage Is the Lazy Target. Mutation Testing Is the Honest One.
Line coverage is easy to game. An agent can write tests that execute every line and assert almost nothing, and the coverage report will look perfect.
ub-mode pairs coverage with Mutator, which runs mutation testing. The tool makes small changes to your code, such as flipping > to >= or removing a return, then reruns the tests. Any change the tests fail to catch is a surviving mutant, and it marks a gap in your assertions.
Consider a limit check like if (balance > limit). Suppose the tests cover the branch but only use balances far above and far below the limit. Mutator changes > to >=, the tests still pass, and the boundary is untested. The fix is one assertion at exactly balance == limit. Coverage would have reported that line as green the whole time.
ub-mode's instruction is to "cover the uncovered, kill the survivors, delete dead code." The last part is worth noting. Dead code can survive mutation testing indefinitely, and deleting it is often the cheapest way to improve your score.
Duplication: The Threshold Needs Checking
Dryer detects structural duplication. The README gives two different values: one line says duplication should stay "< 0.8," while another says duplicate blocks with "≥ 0.8 similarity" should be eliminated. These describe the same threshold from opposite directions, but the comparison operator and the direction of the score matter if you're writing a CI rule.
Don't guess. Read Dryer's own documentation to confirm what the number measures and which way it's compared.
The problem Dryer targets is one agents create constantly. Ask for three HTTP handlers and you'll often get three nearly identical validation blocks. Each copy looks reasonable on its own, and the duplication only becomes visible when the rules change and one copy gets updated while the others don't. Extracting the shared logic early keeps the change in one place.
Comparing the ub-mode Quality Gates
| Tool | What It Measures | ub-mode Threshold | Failure It Catches |
|---|---|---|---|
| Crapper | Cyclomatic complexity, coverage, CRAP per function | CRAP < 10 | Complex functions and untested logic |
| Dryer | Structural code duplication | Similarity ≥ 0.8 (README wording is ambiguous) | Copy-pasted blocks that drift apart |
| Mutator | Mutation score, surviving mutants | Kill survivors; no numeric target stated | Weak assertions that coverage misses |
| uml-viewer | Components, dependencies, coverage, CRAP, mutation scores | Visualization only | Dependency direction problems that are hard to see in code |
The table shows a pattern: three gates enforce rules, and one helps you see the results. Teams often add visualization first and enforcement later. ub-mode reverses that order.
Instructions Guide the Agent. Gates Enforce the Result.
Here's the part most readers will miss. A skill file is still a prompt. The agent reads it, usually follows it, and occasionally doesn't. No amount of careful wording changes that.
The quality gates are different. Crapper either reports a function above 10 or it doesn't. Dryer flags the duplicate or it doesn't. These checks are deterministic, so they don't depend on the agent's mood or context window.
That's why the setup works best when you run the gates yourself, not just ask the agent to report on them. If the agent says "all functions pass CRAP," run Crapper and read the output. The skill is a discipline you describe to the agent. The tools are the audit.
Installing and Running ub-mode
Setup takes a few minutes:
- Copy
SKILL.mdinto your agent's skills directory asub-mode/SKILL.md. The README gives examples such as~/.claude/skills/ub-mode/SKILL.mdand~/.cursor/skills/ub-mode/SKILL.md. - Invoke the skill with
/ub-modein your agent session. - Install Crapper, Dryer, and Mutator from their repositories so you can run the gates locally.
Skill directory paths can change between agent versions, so check your agent's current documentation if the examples don't match what you see.
Frequently Asked Questions
What is the ub-mode agent skill?
The ub-mode agent skill is a SKILL.md file that instructs an AI coding agent to follow a set of software engineering practices. These include test-first development, behavior-focused testing, and small ordered commits. It's designed to be paired with the Crapper, Dryer, and Mutator tools, which check the code the agent produces against measurable thresholds.
How do I install ub-mode for my AI coding agent?
Copy SKILL.md into a folder named ub-mode inside your agent's skills directory, then invoke /ub-mode in a session. The README lists locations for Claude, Cursor, and Grok. Install the companion tools separately if you want to run the quality gates yourself.
Why does a CRAP score of 10 fail the ub-mode check?
ub-mode requires CRAP to be strictly below 10. CRAP is at least as large as the function's cyclomatic complexity, so a function with complexity 10 or more can't pass, even with full test coverage. Splitting the function into smaller pieces is the usual fix.
Does ub-mode replace running tests and linters?
No. It adds a discipline layer on top of your normal test suite. Mutator and Crapper measure things your existing tests may not check, but they don't replace unit tests, integration tests, or code review.
Use the ub-mode agent skill on one small feature this week, run Crapper and Mutator on the result, and note how many gates fail on the first attempt. Pass this to a teammate who keeps shipping untested helper functions, and let the numbers start the conversation.