TL;DR
ai-badger ships twenty-two skills — named procedures an agent invokes the way you'd hand a task to a colleague who has done it before. I open one of them most days and had never written down what the rest do. This is that list: what each is for, what it writes to disk, and the situation that makes you reach for it.
Thirteen arrive the moment you scaffold a repo, plus a fourteenth if you are on Claude Code. The other eight are opt-in: catalogued, but written only when a project names them. Those get a shorter treatment near the end, because a skill you have to ask for is one you already know you want.
The one with the buttons goes first.
Fourteen decisions, four buttons each
Here is what an agent hands me when I ask it to review its own night's work.

That page is generated. The agent finishes a long stretch of work, collects everything it could not decide alone, and writes an HTML file next to the design document. One card per decision. Each card carries a claim in present tense, the minimum detail needed to rule on it, and a line saying what happens if the call goes wrong. Then four buttons — Approve, Change, Reject, Defer — and a notes box.
I click through it in the browser. When I press Save feedback, it writes a markdown file into the same folder. The agent has been watching that path in the background and picks it up.
Why a form, and not a conversation
I used to paste the document into chat and type my answers back as prose. It does not work. The mapping from answer to question survives about four decisions, then quietly falls apart — I answer three of them in one paragraph, skip one, and the agent reconstructs which was which by paragraph order. Sometimes correctly.
The next attempt was answer slots hand-edited into the markdown. Better, and still lossy: a slot shaped like a single line hid my multi-line answers, and a reader parsing only the marker line reported six points unanswered when every one of them had a written answer sitting directly underneath it.
A form cannot lose the mapping. The verdict is a button inside the card; the note is a textarea inside the card. The DOM enforces the join that prose kept dropping.
The counter in the footer does the other half of the job. "0 of 14 answered" is not decoration — the output file has a ## Not answered section, and the skill instructs the agent to reconcile it out loud rather than assume silence meant yes.
What "a skill" means here
A skill is a markdown file. The description at the top tells the agent when this procedure applies; the body tells it how. Most of mine ship a helper script alongside, and the split is deliberate — the script does the mechanical part deterministically, the agent does the part that needs judgement. Writing that boundary down is most of the work of making one.
Some are invoked by name, the way you'd call a slash command. Some are hooks: they sit on an event and fire without anyone asking. I have flagged which is which below.
In Claude Code the install is two lines:
/plugin marketplace add https://github.com/Arasz/ai-badger
/plugin install ai-badgerThat installs the skills themselves and nothing else. Nothing is written into your repository until you run welcome-ai-badger in it, which is the next one on the list.
Setting up, updating, contributing back
Three skills that move content between the framework and a repo, in three directions.
welcome-ai-badger — invoked by name. Point it at a repository and it works out which stacks are in play, which agents are present, and what the build and test commands are. Then it materialises a .ai-badger/ folder: the skills you selected, the personas, the invariants, path-scoped instructions, and an assembled CLAUDE.md (or HERMES.md, or .github/copilot-instructions.md — whichever agents live in that repo). Everything it wrote is recorded in a manifest, which is what makes the other two skills possible.
When I reach for it: a repo where I keep re-explaining the same conventions to the agent every session.
den-refresh — framework to project. It checks what changed upstream, backs up your .ai-badger/ folder, re-scaffolds with the config you already have, and reports the difference. Files that are seeded once and then yours — session state, marker context — are preserved rather than overwritten.
When I reach for it: a drift notice appears, or I shipped a framework version and want last month's repos to catch up.
feed-badger — project back to framework, the direction people usually skip. It diffs your .ai-badger/ against the manifest to find what you changed by hand, sorts each change into agnostic, generalisable, or project-specific, strips the repo names and domain terms out of the keepers, and opens a draft PR against the framework. It refuses anything it judges project-specific, which is most of what I try to feed it.
When I reach for it: I fixed the same instruction in three repos and it should stop being my problem.
Running the work
task — invoked by name, as /task <id>. It runs one backlog item end to end as a separated unit: register the task, branch, delegate planning to a high-reasoning model, hand implementation to cheaper models, run the project's own build and test commands, gate the result through a reviewer, and record what it cost. If the repo's config names GitHub, the PR and review-round handling switch on too; if it doesn't, that part stays off rather than assuming a platform.
The reason it exists is the tracking. It writes token usage per task, split by model, so after the fact I can ask which model actually did this work rather than guessing. That number is what the last article was about. It also records a resume command, so a session that dies at 3 a.m. is recoverable rather than restarted.
When I reach for it: anything that will take more than one sitting.
create-task-spec — invoked by name. It turns a vague idea into a specification by interrogating me for what I know, rather than drafting something plausible for me to approve. The output is two files: a Gherkin .feature describing the behaviour, and a spec.json holding everything Gherkin cannot — scope, what is explicitly out, constraints, and which questions I deferred rather than answered. task takes the manifest path in place of a title.
The polarity is the whole point, and my first design had it backwards. I had the skill proposing two to six plausible business rules for me to approve — which is what the closest prior art does, and it produces a document that reads as agreed and is actually the model's guesses wearing your name. Shown six rules, nobody writes a seventh. They edit the six.
That failure is invisible from the outside, which is what makes it worth designing against rather than noting. The spec looks finished either way.
So the contract inverts: never assume, offer options to choose between rather than content to accept, and treat "I don't know" as a recorded deferral with a fallback picked on the spot instead of a gap that quietly closes.
Gherkin is doing structural work here, not decorative. Its grammar has required slots, so an empty one is the next question — the interview script comes from the artifact instead of from a checklist I invented. And incompleteness is countable: a Rule with no example and an example with no steps are facts about the file, not judgement calls, so a 173-line stdlib script answers "are we done?" without an opinion. Gherkin is line-oriented, so this needs a scanner rather than a parser — no dependency, which matters in a repo whose floor is the standard library plus jsonschema. The loop stops when the document is complete rather than when the conversation has gone on long enough.
No BDD framework is involved, which is not where I expected to land. I went in intending to target SpecBinder — Dmytro Stasyuk's annotation processor that compiles Gherkin into JUnit tests at javac time — and spent an afternoon designing around emitting two files for it, a .feature and a .specb, before reading its config table properly. supportedFileExtensions defaults to {"feature", "specb"}. They are the same format under two names. The second file would have been a copy of the first, and worse than useless: its convention-based discovery would have generated two test classes from one spec.
That killed the dependency but not the idea. The format alone carries the value when the reader you care about is an agent, and it costs nothing to adopt.
When I reach for it: anything where the alternative is discovering in review that we built the wrong thing, precisely.
differential-feature-refactor — invoked by name. It produces a side-by-side of what the code does now against what it is supposed to do, and a human annotates the gap before anyone scopes a refactor. The output is a markdown file with a fixed shape: a header naming the decisions that count as authority, four Mermaid flow views drawn twice — have and will have — and, inside the section it belongs to, every question the agent could not answer alone:

It exists because of a specific bad week. A design that had an ADR behind it was reimplemented in parallel thirty-six minutes after it landed — the second version with no decision record of its own. Five days later the original read as dead code and came close to being deleted, which would have taken out a live integration path with it. Twenty-odd documents described that architecture and at least one of them described it falsely. The skill exists to make design intent legible before somebody acts on the wrong reading.
When I reach for it: two implementations of the same idea and nobody can tell which one is the deliberate one.
code-review-checklist — invoked by name. A preflight checklist in the aviation sense: sequential phases, every item a concrete check you can pass or fail, nothing skipped because the reviewer is experienced. Stack-specific items get merged in from the repo's own config, so a .NET repo and a TypeScript repo get different lists.
When I reach for it: reviewing a diff and finding myself producing impressions instead of findings.
Keeping the agent honest
Four skills that are mostly about the agent's behaviour rather than the code.
prompt-markers — a hook on prompt submission. Three prefixes, detected mechanically:
| Prefix | What it means | What the agent must do |
|---|---|---|
h: / hint: | A lead, not an instruction | Research it before acting, and report what it found |
f: / feedback: | A correction | Handle it before anything else in the queue |
e: / extension: | Widen the scope | Fold it in, or flag it as a follow-up if too large |
The point is that it is mechanical. A model reading tone alone gets this wrong inconsistently, and gets it wrong more often the longer the session has been running. I used f: twice while writing this article.
commit-reminder — a hook after every edit. It watches how many files are dirty and, past a threshold, tells the agent to commit. It is phrased as an instruction rather than a suggestion, because "consider committing" is advice a mid-task agent declines every time.
It never blocks the tool call that triggered it. That restraint is deliberate and load-bearing: it replaced a third-party plugin that intercepted every write and forced an OAuth login before letting the call through.
When I reach for it: I don't. It is always on, which is the point.
auto-wm — Claude-specific, invoked by name. Auto-approves tool calls for a bounded window so long work does not stall on permission prompts. Two modes: partner, where I'm at the keyboard and the agent can still ask me questions, and away, where it can't, because there is nobody to answer.
Three guards, re-checked on every event. The window expires on wall-clock time and is capped at twelve hours. It only applies inside the directory it was enabled in, so arming it in one repo does not arm it machine-wide. And a denylist — recursive deletes, sudo, force-pushes, piping the network into a shell, writes outside the project, among others — is never auto-approved, no matter which mode is on. Every decision goes to an audit log.
When I reach for it: a four-hour job I want to start and walk away from.
call-behaviorist — invoked by name, off by default, writes nothing and creates no directory until you switch it on. Then it keeps an append-only log of which hook ran, in which project, under which version of the code that actually ran — which is how a stale plugin copy becomes visible.
It exists for one question: did that hook even fire? Without a log, answering it means adding print statements and re-scaffolding.
Keeping the instructions true
maintain-agent-instructions — invoked by name. If you run more than one agent, you have more than one instruction file, and they drift. This keeps one compact always-loaded entrypoint per agent plus detailed path-scoped files behind it, and — the part that matters — keeps the model of what should be in them machine-readable, so drift is a script check in CI rather than something you notice six weeks late.
When I reach for it: CLAUDE.md and copilot-instructions.md have quietly stopped agreeing.
mcp-index — invoked by name. Every MCP server you connect adds its tool definitions to the prompt, and past a certain number the agent starts picking the wrong one. This maintains an index mapping each tool to tags and a plain-language intent; a hook then recommends the relevant few for the turn, so the agent picks from a shortlist instead of weighing the whole catalog.
I built it after watching an agent grep its way through a repository that had a knowledge graph sitting one tool call away.
What it refuses to do
A generated review form got committed with /Users/arasz/… baked into one of its config fields. Nobody typed that path — a template filled it in, and the file went into a public repository with my home directory in it.
That is mild as disclosures go. What makes it worth writing down is the shape: it arrived by generation, so no amount of care while typing would have caught it. Most of what I have added to `SECURITY.md` since is that shape.
The threat model is one sentence. Every skill here writes files, several run commands, and one opens a pull request against a public repo from a private one — so the dangerous direction is outbound and side-effecting, not inbound parsing. Nobody is going to feed this a malicious YAML. Someone is going to have it write somewhere they did not expect.
The guards that follow from that are all refusals.
Install commands are argv lists, never strings. No shell=True anywhere, and the template is tokenised before substitution, so a value containing a space or a ; stays one argument instead of becoming two. Nothing installs silently either: the dependency check prints what it would install and where, and --execute is how you agree to it.
A task id cannot escape its directory. The task skill splices <taskId> into .ai-badger/worktrees/<taskId> and hands that to git worktree add — and on cleanup, git worktree remove. A .. in that argument would have pointed a removal somewhere nobody asked for.
It refuses such an id rather than quietly rewriting it. That is the part I would argue for: a sanitised id stops matching the one in the tracking file, and a containment fix that creates a correctness bug has not fixed anything, it has moved the bug somewhere quieter.
A generated page cannot phone home. The research skill renders findings to HTML you open in a browser, built from repository content — so anything it can fetch is a path out of a machine that has your repository on it. No <script src>, no CDN, no fonts, no fetch. I check it by grepping the output for http, and the count is zero, which is a weaker test than it sounds and still the one I would keep. It also refuses to be written inside the repository, which is what stops it becoming the review form above.
Secrets are scanned on every branch push, not only the ones that become pull requests. A credential pushed to a public remote is exposed the moment it lands.
There is deliberately no secret-scanning pre-commit hook, and that reasoning is the one I would defend hardest. The obvious candidate matches a tracked test fixture on a deliberately fake value, so it would ship with a permanent exception from its first run — and a scanner with a permanent baseline is theatre. Five patterns advertised as secret scanning is worse than none: it buys confidence it has not earned. The real scan runs in CI, where it can afford full history and a rule set someone else maintains.
I found every one of these the same way. Not by threat-modelling — by trying to do something reasonable and being told no.
When I reach for it: never directly. That is what a refusal is for.
The eight you have to ask for
These are catalogued but not installed until a project names them in its config.
Four lean on a knowledge graph of the repo, and all four exist because the default answer to "go read the codebase" is an agent grepping in the dark. explore-codebase orients in territory nobody on the team has read recently — the "what is here" question rather than "where is this specific thing". debug-issue traces the call chain from a symptom back to its entry point before anyone starts hypothesising, which is reliably the step that gets skipped. refactor-safely enumerates every affected location before a rename or a removal, so the blast radius is known rather than discovered. review-changes ranks a diff's changed units by blast radius and checks whether the riskiest ones are tested at all.
Three deal with documentation, and which one you want depends on what you already have: scaffold-documentation creates the canonical tree in a repo with none, update-documentation makes docs match something that already changed and decides where a new page belongs, and migrate-documentation reorganises an existing tree wholesale. That last one is resumable, because that job does not finish in a sitting.
The three documentation skills install as a group, because they read each other's reference files in place — name any one of them and you get all three. That is a fact about the catalog rather than a convenience: ask for the migration skill alone and every reference path in it dangles, which is exactly what happened before anyone noticed.
evidence-first-research is the newest and the one I argued for hardest. It grades every finding by how you know it — measured, read, inferred, or unverified — and the renderer refuses a report where a claim carrying a number has no evidence line under it.
I wanted it because I published a cost figure of "three to five minutes per push, about an hour across fifteen pushes" in a changelog and a pull request body. Measured, it was 75 seconds and nineteen minutes. Nothing in the format made the unmeasured number look unmeasured, and it was caught only because I re-derived it by hand afterwards.
They are opt-in for one reason: they are the likeliest to disagree with how your repository already works, and a skill that fights your conventions is worse than no skill.
The whole set
| Skill | For | How it runs |
|---|---|---|
owner-gate-review | Per-decision rulings that stay attached to their decision | By name |
welcome-ai-badger | First scaffold of a repo | By name |
den-refresh | Pull framework updates into a scaffolded repo | By name |
feed-badger | Contribute a repo's improvements back | By name |
task | Run one backlog item as a tracked unit | By name |
create-task-spec | Interrogate an idea into a spec worth building from | By name |
differential-feature-refactor | Tell design intent from accumulated cruft | By name |
code-review-checklist | Findings instead of impressions | By name |
prompt-markers | Signal how to treat a prompt | Hook |
commit-reminder | Stop work sitting uncommitted | Hook |
auto-wm | Bounded auto-approval for long runs | By name (Claude only) |
call-behaviorist | See what the machinery actually did | By name |
maintain-agent-instructions | Keep multi-agent instruction files in agreement | By name |
mcp-index | Recommend the right MCP tool | By name + hook |
explore-codebase | Orient in unfamiliar territory | By name (opt-in) |
debug-issue | Trace a symptom to its entry point | By name (opt-in) |
refactor-safely | Know the blast radius before moving anything | By name (opt-in) |
review-changes | Rank a diff by risk, check the risky parts are tested | By name (opt-in) |
scaffold-documentation | Create a docs tree where there is none | By name (opt-in) |
update-documentation | Make the docs match what changed | By name (opt-in) |
migrate-documentation | Reorganise a docs tree wholesale | By name (opt-in) |
What I would take first
owner-gate-review, and it isn't close. It is the smallest change to how I work and the only one that survived contact with a tired evening — the difference between an agent asking me fourteen questions in a paragraph and an agent asking me fourteen questions I can answer one at a time.
If you take a second, take task, and read what it records about cost after a week. I did, and it turned into an article's worth of things I was wrong about.
What I cannot tell you is whether any of this helps on a codebase that isn't mine. Every one of these came out of a specific thing going wrong in my own repositories, which is a good way to get skills that work and a bad way to get skills that generalise. The framework is at github.com/Arasz/ai-badger — MIT, and each skill is one readable markdown file, so taking a single one and leaving the rest is a legitimate way to use it. If you do that and it breaks somewhere I did not anticipate, that is the report I want.