Skip to main content
MindStudio
Pricing
BlogAbout
My Workspace
unlazy skillClaude Code skillCodex CLI

Unlazy: The Skill That Stops AI Coding Agents From Faking "Done"

Unlazy is a free Claude Code and Codex CLI skill that forces agents to prove work is finished with runnable checks, not confident claims.

Edited by Luis Chavez-Mattos, Director of Product RSS
Unlazy: The Skill That Stops AI Coding Agents From Faking "Done"

What is Unlazy and what problem does it solve?

Unlazy is an open source skill for Claude Code and Codex CLI, built by developer Leon X (LNX), that makes AI coding agents prove their work instead of just declaring it finished. Anyone who has run a long agent session knows the pattern: the model reports “done, everything implemented and tested,” and then you check the code and find placeholders, skipped tests, and missing features. Unlazy replaces that self-reported confidence with a file called gates.md, an acceptance ledger of runnable checks that must actually pass before the agent is allowed to say a task is complete.

The project is written in plain Node with no third-party runtime dependencies, needs Node 16 or newer, and is MIT licensed. It works as a skill inside Claude Code and Codex CLI, meaning it slots into an agent’s existing workflow rather than requiring a separate app or service.

TL;DR

  • Unlazy forces agents to write an acceptance ledger before doing work, a gates.md file where every gate has a shell command to run and a success marker the output must contain.
  • A gate only counts as met if the check command exits with code zero and the expected text appears in the output, so a checkbox alone means nothing without recorded evidence.
  • Agents can’t quietly delete gates they can’t satisfy, they have to mark them abandoned with a stated reason, and that abandonment shows up in the final report.
  • Installation is a single command through Vercel Labs’ skills CLI (npx skills add leongx/unlazy), with flags for a user-level install or installing across every detected agent on the machine.
  • An approval system stores every approved check outside the repo, bound to the exact command, working directory, shell, and environment, so a swapped-in malicious command in an untrusted ledger won’t silently execute.
  • For large tasks, Unlazy can split work into a “depth tree” of leaves with narrow ownership over specific files, each with its own ledger, and re-verifies every leaf’s gates before accepting its results.
  • The project’s own documentation is unusually candid that its cited research on LLM laziness motivates the design but doesn’t prove a fixed performance improvement.

How does the gates.md ledger actually work?

The core mechanic is simple to describe and strict in practice. Before an agent starts real work, it writes gates.md, listing each expected outcome as a gate. Every runnable gate needs two lines: a check line, which is a real shell command, and an expect line, a success marker that must appear in that command’s output.

A gate is only “met” when both conditions hold: the check command exits with status zero, and the expect text is found in the combined output. When that happens, the checker writes an evidence line into the ledger recording the resolved shell command, the working directory, the exit status, a path fingerprint, and the decisive output snippet. A checkbox with missing or pending evidence is treated as unmet, full stop.

If a gate turns out to be impossible to satisfy, the agent can’t just erase it. It has to add an abandon line with a non-empty reason, and that gets surfaced in the final report. This detail matters: it prevents an agent from quietly narrowing scope to make the ledger look cleaner than the actual state of the work.

The project’s documentation is also honest about the limits of this approach. The checker can only verify that the command you wrote behaves as declared, not that the plain-English gate title actually matches what the shell command tests. Its guidance pushes toward gates that read the real artifact, print a success marker only after all assertions pass, and test negative checks against a known positive control, rather than, say, copying a number the agent supplied into the expect line as if that proves anything.

How do you install Unlazy?

The simplest path is Vercel Labs’ skills CLI:

npx skills add leongx/unlazy

A -g flag installs it at the user level, and an --all flag installs it for every AI agent detected on the machine. For a manual install, you clone the repository into the relevant skills folder: .claude/skills in your home directory for Claude Code, or .codex/skills for Codex CLI.

Once installed, you invoke it with /unlazy in Claude Code or $unlazy in Codex CLI. It also responds to natural language triggers, so phrases like “tree five gates” or “literally do not stop until it is done” will activate it without typing the exact command.

What does running Unlazy actually look like?

A solo run starts by copying the provided leaf template into a gates.md file and filling in the specific gates for the task. Then you run the gate check script with a --status flag, a report-only mode that parses the ledger and shows what’s met and unmet without executing anything.

Because check lines are literal shell commands, the documentation is explicit that you should read every command, and every script those commands call, before running anything. On a fresh run with no prior approval record, the checker won’t execute pending commands. It prints the resolved command, the expectation, the working directory, the shell, and the path, then stops. Once you’ve reviewed everything, running again with --approve approves each pending command and executes it.

Approvals are stored outside the project repository, in a .unlazy folder in the home directory, and each one is bound to the exact ledger, gate, check and expect text, working directory, shell, timeout, platform, and inherited path. Change any of those, even slightly, and it requires approval again. That means pulling in a ledger from an untrusted source, where a command has been swapped, won’t silently execute the new command.

A --reverify flag reruns every runnable gate, including ones already marked complete, because stored evidence from a previous run isn’t treated as proof for a new state of the code.

How does Unlazy handle large, multi-part tasks?

Unlazy has three modes: solo (a single ledger, as above), orchestrated, and parallel. For larger builds, it uses a “depth tree” structure, triggered with something like /unlazy tree 5, refactor the payment module. The requested task becomes layer one, then gets split at real domain and component boundaries into leaves, each a coherent deliverable with a narrow contract, defined file ownership, and its own gates.md.

Everything lives under a .unlazy scope folder in the project, with a plan.md that fixes interfaces, dependencies, conventions, and file ownership before any work gets dispatched. Each leaf gets its own ledger, and branches above the leaves get integration gates covering interface compatibility, end-to-end behavior, and regressions.

The documentation explicitly warns against padding out tree depth just to hit a requested number: if the requested depth would force filler leaves, the skill is supposed to flag the mismatch and use the closest honest decomposition instead.

For parallel execution, each leaf declares “OWNS” paths, repository-relative globs of files it’s allowed to write, and two concurrent leaves can never own the same path. Dispatch is rolling, so a newly unblocked leaf starts immediately rather than waiting on unrelated work. When a leaf reports completion, the parent doesn’t take its word for it: it reruns that leaf’s gates with --reverify. Verification flows upward from leaves to root, and the final report only happens once the root ledger is satisfied, with every number remeasured right before reporting.

For Claude Code specifically, there’s an optional stop hook. While a session’s ledger has unmet gates, the hook blocks the agent from ending the session and declaring victory. It doesn’t run any checks itself, and it has a built-in release valve: after six consecutive blocks with no ledger progress, it lets go, avoiding an infinite loop. The skill is designed to never install this hook without explicit consent.

Is Unlazy worth using?

For quick edits or simple questions, no. Writing a full gate ledger for a one-line fix is overhead the task doesn’t need, and the project’s own documentation says as much. The value shows up on substantial work: long refactors, audits, and parallel multi-file builds, where the cost of a quietly incomplete result is far higher than the cost of maintaining a ledger.

VIBE-CODED APP
Tangled. Half-built. Brittle.
AN APP, MANAGED BY REMY
UIReact + Tailwind
APIValidated routes
DBPostgres + auth
DEPLOYProduction-ready
Architected. End to end.

Built like a system. Not vibe-coded.

Remy manages the project — every layer architected, not stitched together at the last second.

It’s also worth being clear-eyed about what the approval system does and doesn’t protect against. Approval is consent, not sandboxing. Once you approve a check, it runs with full access to your machine. The “read every command before you approve” step in the documentation isn’t a suggestion, it’s the actual security boundary.

On the evidence side, the project cites research on LLM laziness, underthinking and overthinking, and long-horizon task degradation, including benchmark work where top-performing agents passed a low percentage of checkpoints on long iterative tasks. But the documentation is upfront that this research motivates the design rather than proving Unlazy delivers a specific, measured improvement. Earlier versions referenced an internal comparison across a small number of runs, and the current documentation acknowledges the raw artifacts for that aren’t available in the repository. That level of honesty about what’s proven versus what’s plausible is rare in a space full of tools claiming dramatic gains with no evidence attached.

Frequently Asked Questions

What is the gates.md file in Unlazy?

It’s the acceptance ledger an agent writes before starting work. Each entry, or gate, describes one observable outcome with a shell command to run and a text marker that must appear in the output for the gate to count as met.

Does Unlazy work with tools other than Claude Code and Codex CLI?

Based on available documentation, Unlazy is built specifically as a skill for Claude Code and Codex CLI. It installs into each tool’s respective skills folder and is invoked through their command interfaces.

Does approving a check mean it runs in a sandbox?

No. Approval means you’ve reviewed and consented to a specific command, but the command still executes with full access to your machine. The documentation is explicit that reading every check before approving is a required step, not optional caution.

Can an agent hide parts of a task it couldn’t finish?

Not without it showing up in the report. If a gate can’t be satisfied, the agent has to mark it abandoned with a stated reason rather than deleting it, and that abandonment is surfaced when the final results are reported.

Is there proof Unlazy improves agent performance by a specific amount?

The project’s documentation cites general research on AI agent laziness and long-horizon task degradation as motivation for its design, but it explicitly does not claim a fixed, proven performance improvement, and it acknowledges that earlier internal comparisons lack published raw data.

Editorial standards

Presented by MindStudio

No spam. Unsubscribe anytime.