# Ponytail: Smaller AI Code, With Correctness Before Cleverness

A read-only AI audit found seven serious issues in a billing portal. We explain Ponytail&#39;s rules, useful commands and the checks we require before accepting a fix.

Author: J.A. Watte
Published: October 21, 2026
Source: https://jwatte.com/blog/ponytail-lazy-senior-dev-ai-coding-agents/

---

We tried Ponytail's audit method on a small-business billing portal we run. It returned seven serious findings and one maintenance item. None needed a new framework. The useful work was tracing what happened when an ordinary operation failed halfway through.

The name can mislead. A tool sold as a lazy senior developer sounds like something that only deletes code. Its audit puts correctness first and smaller code last.

## What Ponytail adds

[Ponytail](https://github.com/DietrichGebert/ponytail/blob/main/README.md), by Dietrich Gebert, is a set of written rules and commands for AI coding agents. It pushes the agent toward the simplest complete change: reuse the project's code, try the standard library or platform, and avoid abstractions nobody requested. YAGNI means you aren't going to need it. Here that means leaving speculative flexibility out until a real requirement arrives.

It also supplies read-only review and audit methods. The [MIT license](https://github.com/DietrichGebert/ponytail/blob/main/LICENSE) permits reuse. The tree ships adapters for Claude Code, Codex, Cursor, Windsurf, Cline, GitHub Copilot, Gemini CLI, Kiro and OpenCode, among others. These are different integrations: some provide commands and hooks; others only load written rules. The [portability guide](https://github.com/DietrichGebert/ponytail/blob/main/docs/agent-portability.md) explains which is which.

In Claude Code, installation registers hooks for `SessionStart`, `UserPromptSubmit` and `SubagentStart`. They load rules at session start, track mode commands on every prompt and supply rules to spawned subagents while active. The prompt hook does not reload the full rules on every ordinary message. Node.js must be available. The plugin also adds a band above the prompt and a local task board on supported Claude Code surfaces. Its optional ledger is enabled by default: after each turn, it updates a per-project CSV in Ponytail's band folder under your user configuration directory.

The [plugin manifest](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json) lists the controls. The ledger records cost, turns, agent time, tokens, reuse and test status. An optional webhook sends a task snapshot as JSON to an HTTPS destination you configure. Its address is empty by default. No Ponytail webhook transmission happens unless you set it.

Ponytail is not a linter, a test runner or a guarantee. It gives an agent instructions. Whether the agent follows them, and whether its conclusion is true, still needs checking.

## Install it, or use one method once

For Claude Code, send these as two separate prompts, as the [installation guide](https://github.com/DietrichGebert/ponytail/blob/main/INSTALL.md) specifies:

```text
/plugin marketplace add DietrichGebert/ponytail
```

```text
/plugin install ponytail@ponytail
```

The default level is full. Lite builds what you asked for and names a smaller alternative. Ultra also challenges requirements that seem unnecessary. These are behavior settings, not measured quality levels.

To turn the mode off for the session:

```text
/ponytail off
```

For future sessions, set `PONYTAIL_DEFAULT_MODE=off`. To remove the Claude Code plugin, the current guide documents:

```text
/plugin remove ponytail
```

Removal can leave external state and an old statusline setting behind. For complete cleanup, read the guide's uninstall section before removal. It describes running the bundled cleanup script while the plugin files still exist. Turning off the coding mode is also distinct from hiding the band or disabling its ledger.

### Commands we would reach for

These examples are prompts we wrote, not output from a benchmark. Review and audit report findings without changing code; the everyday mode guides implementation.

| Command | When to use it | Example prompt |
|---|---|---|
| `/ponytail` | Everyday coding | `/ponytail full` then ask: Add a download button using our existing button component. |
| `/ponytail-review` | A diff, branch or pull request | `/ponytail-review staged changes. Check callers outside the diff too.` |
| `/ponytail-audit` | A whole repository or named folder | `/ponytail-audit the import package. Assume one daily batch. Report only.` |
| `/ponytail-debt` | Deliberate shortcuts | `/ponytail-debt list the limits and revisit triggers. Do not edit.` |
| `/ponytail-gain` | Read the published benchmark scoreboard | `/ponytail-gain show the benchmark, not estimated savings for this repo.` |
| `/ponytail-help` | Check available modes and commands | `/ponytail-help explain the levels before we change one.` |

The [review method](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-review/SKILL.md) reads connected code, including callers outside the diff. The [audit method](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-audit/SKILL.md) maps the repository first. A command that only loads instructions cannot enforce read-only access by itself. Set that boundary in the agent's permissions and working environment too.

### A small example of lazy done properly

Suppose we ask for the unique labels in a Python list, keeping their first-seen order. An agent could add a package or build a collection class with configurable sorting. For a modest list of strings, Python's built-in dictionary already does the job:

```python
labels = ["blue", "green", "blue"]
unique_labels = list(dict.fromkeys(labels))
```

The result is `['blue', 'green']`. This is our illustration, not a measured before-and-after result. It assumes hashable strings and keeps case distinctions. A request for case-insensitive matching would need another decision. Small code stays small by stating its scope, not by silently changing the requirement.

Deliberate limits get a `shortcut:` comment. Here is a separate Python example for a disposable, single-process preview:

```python
# shortcut: preview state lasts one process, use persistent storage before sharing across workers.
preview_cache = {}
```

[The debt command](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-debt/SKILL.md) collects these comments into rows with their location, limit and upgrade trigger. It flags missing triggers. It reports by default; ask explicitly if you want the ledger saved. This debt report is separate from the band's CSV task metrics.

### Without installing anything

We did not install Ponytail for our audit. We pasted its audit method verbatim into a brief for an unattended Codex job. The agent read the repository read-only, reproduced findings in a throwaway clone with synthetic data, and wrote a report to a file. Claude then re-read the code for every finding before we accepted it.

We can use that pattern with a non-interactive coding agent, including Claude Code's `-p` mode. The useful extra brief is short:

```text
Apply the attached audit method. Read the source repository only.
Use a disposable clone and synthetic data for reproductions.
Do not contact production services or read secrets or customer data.
Write the report to the designated report file. Change no source code.
State assumed load, concrete failure cases and everything not checked.
```

This keeps the method scoped to one job. It avoids adding hooks to every later session and gives a second reviewer a durable report to challenge. It does not reproduce the installed plugin's whole behavior or establish its cost savings. Our [Codex drafts, Claude reviews workflow](/blog/sovereign-ai-model-routing-local-codex-claude/) covers the broader division of work.

## What our audit found

The target was a small-business billing portal we run (card and bank payments, a scheduled billing job, about 50 customer accounts). We asked the reviewer to spend its attention where a mistake could lose money or give someone the wrong access.

The method's order was explicit: correct, safe, holds under load, tested, fast, lean. The resulting report contained seven serious findings and one maintenance item. We are describing the classes here, without publishing application details.

| Finding class | Why it mattered |
|---|---|
| A safety note before charging could fail silently | A payment could proceed without the durable record needed for recovery. |
| Multi-step money changes saved separately | Two findings involved operations that could stop partway through instead of succeeding or failing together. |
| Paused-account protection covered only some money actions | Several money actions could still change an account that should stay locked. |
| An email-ownership check skipped one account category | The check could misjudge whether an address already belonged to someone. |
| Cancelling a combined bank payment marked only one account | Other accounts covered by the same payment could retain the wrong state. |
| A reservation could get stuck | A failed step could leave it unavailable without the record needed to release it. |
| Development-only package advisories | Maintenance was needed, while the production-only dependency audit reported zero vulnerabilities. |

Each finding had four plain-English parts: what this is, problem, fix, and if we skip it. That format let us understand the consequence before deciding what to change. The private report retained the evidence; this article deliberately omits reproduction details.

The audit job reproduced all seven serious findings with synthetic data in a disposable clone. We then used Claude to re-read the code for each one. That review confirmed all seven and widened one. The report named one action that skipped the paused-account lock; reading the code showed several more with the same gap. We fixed the whole class rather than treating the first report as the final word.

The release loop we require next is one fix release, with a back test for each finding. A back test runs the new regression check against the old code and proves it fails, then runs it against the fix and proves it passes. That checks whether the test can detect the defect. A green test written after a fix alone cannot show that.

After those checks come staging, deployment and a second audit. We are leaving the final release results for verification rather than claiming a completed recovery from the first report.

<!-- CLAUDE-FILL: back-test table and re-audit result -->

## Why the method helped

**It fixes the priority order.** Ordinary AI reviews can drift toward tidy helpers while missing broken money flows. Ponytail ranks correctness and safety before leanness. In our run, all-or-nothing writes mattered more than removing lines. A transaction groups related database changes so they succeed together or leave no partial change.

**It demands a concrete case.** We interpret the [audit rules](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-audit/SKILL.md) as: no concrete case, no finding. A vague warning that something might race is easy to generate. Showing a starting state, a failed step and a wrong result gives a reviewer something to verify or reject.

**It requires an assumed load.** A small portal needs correct handling of overlapping work. That does not automatically justify a distributed queue or another service. Naming the expected workload makes scale advice answerable. Without it, an agent can design for an imaginary company much larger than yours.

**It asks for the smallest complete fix.** The rules prefer reuse and deletion, but require tracing callers first. That counters the common failure of patching the named symptom while leaving a sibling path broken. We still have to check that the proposed smaller change covers the whole problem.

**It makes the report usable.** Numbered findings let a person say fix 2 and 5. The four-part format explains consequences to someone who has never seen the code. The final unchecked-work statement limits the verdict. These details stop a long review from becoming a pile of concerns nobody can act on.

**It separates diagnosis from editing.** Audit and review produce reports. Fixing is a later decision. That gave us room to verify findings before an agent rewrote anything. Written deferrals also keep a conscious shortcut from turning into an undocumented assumption. Our [agent fleet article](/blog/claude-code-agent-fleet-org-chart/) develops that habit of keeping decisions outside a conversation.

These are reasons the process helped us, not proof that the prompt will improve every model or repository.

## What the author's benchmarks establish

The author's [October 7 benchmark](https://github.com/DietrichGebert/ponytail/blob/main/benchmarks/results/2026-10-07-agentic.md) compared Ponytail 5, version 4.13 and no skill using Claude Code with Opus 5.5. It used 39 tasks, five runs per task and arm. The reported reductions against no skill were 53% in source lines, 45% in output tokens, 26% in cost and 41% in time, using geometric means of per-task median ratios.

Those are the author's numbers, not ours. Bash was disabled for all arms; the harness ran generated checks afterwards. Only 18 tasks had executable hidden correctness and safety checks. The pass totals were 87 of 90 for Ponytail 5 and 86 of 90 without a skill. The other tasks and model-judged completeness checks do not establish production quality. This also was not a benchmark of our audit workflow.

The earlier records matter. The [benchmark overview](https://github.com/DietrichGebert/ponytail/blob/main/benchmarks/README.md) acknowledges that single-response comparisons overstated savings against a chatty baseline. The [June cost study](https://github.com/DietrichGebert/ponytail/blob/main/benchmarks/results/2026-06-17-cost-verification.md) found higher costs on some OpenAI reasoning models. The [edge-case study](https://github.com/DietrichGebert/ponytail/blob/main/benchmarks/results/2026-06-16-robustness-audit.md) records email-validation mistakes under standard-library-first pressure. Smaller output is useful evidence, not a reason to skip tests.

## Limits we would keep visible

Lazy can be misread as permission to skip the hard part. Money and authentication still need validation, transactions where appropriate and meaningful tests. A standard-library parser does not become a validator because it is short.

Installed hooks run across sessions and prompts. Review that ongoing behavior before installing. The band and board need supported Claude Code interfaces; the README says they do not appear in `claude -p` sessions.

Review the ledger and webhook separately. When configured, the webhook sends task metrics and identifying fields such as project and session information. Task names are sent by default and can come from the first prompt; `sendNames` can disable them. Leaving the webhook unset prevents this optional transmission, not the coding agent's own normal communication with its model provider.

None of this replaces tests, a staging deploy or a human decision about releasing a change.

## A first audit we would trust enough to review

1. Give the agent read-only access and state the real workload.
2. Use a throwaway clone and synthetic data for reproductions.
3. Require a concrete case and an explicit list of unchecked areas.
4. Verify each finding against the code before authorizing fixes.
5. Add back tests, check the release on a preview or staging copy, then re-audit after deployment.

## Fact-check notes and sources

- All public plugin sources were read October 21, 2026 UTC: [README](https://github.com/DietrichGebert/ponytail/blob/main/README.md), [installation and removal](https://github.com/DietrichGebert/ponytail/blob/main/INSTALL.md), [compact rules](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md), [license](https://github.com/DietrichGebert/ponytail/blob/main/LICENSE), [manifest](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json) and [agent adapters](https://github.com/DietrichGebert/ponytail/blob/main/docs/agent-portability.md). The reviewed plugin version was 5.3.2.
- [Repository metadata](https://github.com/DietrichGebert/ponytail), read through GitHub's API October 21, 2026 UTC: 169,932 stars; created June 12, 2026 at 00:52:37 UTC; last push October 18, 2026 at 01:55:14 UTC; MIT. Stars describe attention, not validation.
- The six [skill definitions](https://github.com/DietrichGebert/ponytail/tree/main/skills), command files, hook definitions, examples, post-install note and all ten [benchmark result records](https://github.com/DietrichGebert/ponytail/tree/main/benchmarks/results) were read October 21, 2026 UTC. Benchmark figures above are attributed to the author; we ran none of the plugin's code, installers or benchmarks.
- Our audit brief and resulting report were read October 21, 2026 UTC. The recorded synthetic observations were made that day, approximately 02:53 to 03:00 UTC. They support the finding counts and production-only advisory count. The second-model confirmation and widened finding come from our editorial brief; private operational records and application details are not published. Release and re-audit results remain pending editorial verification.

## Related reading

- [Model routing: local work, Codex drafts and Claude review](/blog/sovereign-ai-model-routing-local-codex-claude/)
- [The agent fleet and its written operating contracts](/blog/claude-code-agent-fleet-org-chart/)
- [Where skills, rules and memory belong](/blog/claude-code-skills-rules-memory-deep-dive/)

*This post is informational, not technical consulting or financial advice. Mentions of Ponytail, Claude Code, Claude, Opus, Anthropic, Codex, OpenAI, GitHub, GitHub Copilot, Cursor, Windsurf, Cline, Gemini CLI, Kiro, OpenCode, Node.js, Python and Bash are nominative fair use. We are not affiliated with the plugin's author. No affiliation with the other named products or their owners is implied.*


---

Canonical HTML: https://jwatte.com/blog/ponytail-lazy-senior-dev-ai-coding-agents/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/ponytail-lazy-senior-dev-ai-coding-agents.webp
