Eleven Skills and the Rule That Fires Them
Writing a skill for a coding agent is the easy half. The hard half is the policy file that decides when it fires, the artifact directories that let one stage hand off to another, and a scanner that measures what all of it costs.
Everybody working seriously with a coding agent ends up writing skills for it. A skill is a folder with a markdown file in it that says here is how to do this particular kind of work, and writing one is genuinely easy, and about a week later you have eleven of them and the agent is using approximately none of them unless you remember to ask.
That is the actual problem, and it is not a prompt-engineering problem. A skill that fires when you remember to invoke it is a bookmark. What turns a pile of skills into a harness is three things that sit underneath them: a policy file that says when each one fires without being asked, a set of directories on disk that let one stage hand off to the next, and a scanner that measures what the whole arrangement costs you in tokens.
This is a tour of mine. The plumbing that installs it — the symlinks, the generated settings, the shared cross-device memory — is written up separately on the project page; this post is about the skills themselves and how they connect.
The eleven
They fall into three groups, and the groups matter more than the names.
Foundational — these apply inside other work rather than being work of their own.
kiss forces the simplest thing that actually works, climbing a ladder from "does this
need to exist at all" through "is it already in this codebase" and stopping at the first
rung that holds. tdd runs Red→Green→Refactor with verification gates. scientificmethod
makes a falsifiable hypothesis, states a prediction, runs a real experiment, and records
the verdict — so that an untested guess never gets presented as a fact.
The pipeline — investigate turns a thin ticket, or a bare question, into a brief.
plan turns the brief into dependency-ordered work streams. orchestrate turns the plan
into running agents and drives each one to a merged review.
Cross-cutting — temporal-planning reasons in calendar time rather than effort,
because most agents estimate "two hours of work" and then behave as though the task
finishes in two hours, even when the change will sit in a review queue until Thursday.
model-routing picks the model and effort level at dispatch from a static, arguable
table. optimizer turns measured context waste into deterministic tooling.
adversarial-review attacks an artifact before it goes out. wikikb maintains knowledge
bases that compound instead of evaporating.
Two more get named in the policy but do not ship with the skills, and the distinction is
worth keeping straight: code-review is a Claude Code built-in, and taskforge is
a CLI on PATH, not a skill at all — asking for it as one just returns "Unknown skill."
The handoff is a directory, not a conversation
The thing I would change about most agent setups is that the stages talk to each other through the transcript. That works until the session ends, and then the context is gone and the next session reconstructs it badly.
Here each stage writes a file. investigate leaves a brief in .investigations/; plan
reads that and leaves a dependency graph in .plans/; orchestrate reads that and
keeps a status board in .orchestration/. temporal-planning puts wall-clock estimates
in .timelines/. All four directories are gitignored, because they are per-machine
working state rather than configuration.
The payoff is resumability. A plan written on Tuesday by a session that no longer exists is still a file, and a session on Thursday can pick it up without me re-explaining anything. It also means the reasoning is auditable — when a stage gets something wrong I can read what it believed at the time, instead of guessing.
The part that actually makes it work
Skills are inert without something to fire them. The layer that does that is a single rules file which loads into every session, and states for each skill whether it is a MUST or a SHOULD and what the trigger is.
Eleven of these are packaged skills. The two marked built-in and cli are not — they are governed by the same policy file without shipping with it.
Precedence — an explicit instruction from me overrides the defaults for that turn. tdd outranks kiss on tests, without exception: kiss governs how big the solution is, never whether its tests exist.
A few of these earn their place by being annoying.
investigate is triggered by how I phrase a request, not by whether a ticket exists.
If I say "look into", "dig into", "figure out", or "why does…", the skill runs and leaves
a brief — and the rule explicitly refuses the obvious escape hatches: not because the
answer looks obvious, not because it is only one file, not because the context is already
loaded. An answer that felt obvious and was wrong is the exact failure that rule exists to
prevent.
code-review is a MUST before every commit, and the reason is that there is no CI on
these repos. Nothing compiles or tests anything unless a human runs it. A single review
pass over one merged change found six defects, every one reproduced by mutation — a
permission surface widened four-fold by glob expansion, a shell injection through a quoted
directory name, and two assertions that could not fail under any input. None of it was
visible to the test suite, because the tests were part of what was wrong.
Which is the general lesson underneath adversarial-review too: a passing suite proves
the assertions pass, not that they assert anything. So that skill has a rule that a
finding needs a concrete failure scenario or it gets discarded rather than softened into a
nit, and a second rule that any verification in the artifact — a test, a monitor, a gate —
is itself unverified until it has been made to fail on purpose.
Two tools that hold state
taskforge is where the work itself lives. It is file-backed task management for one
human and several agents: markdown with YAML frontmatter, a web UI for people and a
deterministic JSON-emitting CLI for agents, patch-based writes so an agent mutates one
field rather than handing back a whole file with plausible corruption in the parts it was
never meant to touch. It is open source: the project page has the
design write-up, and the code is at
github.com/aarontrank/taskforge.
The rule about it is less about creating tasks than about not lying. Before a session
ends, the task's status has to match reality. An unfinished task is fine —
in-review is a legitimate resting state. The failure is a task still marked running
after the review was posted, because that is invisible to everyone and it makes every
later report wrong.
wikikb is the other one, and it solves the problem where an agent researches something
properly, tells you the answer, and the answer evaporates. It maintains real knowledge
bases — sources kept immutably in raw/, written pages in wiki/, a schema per wiki
saying what page types exist. The single most important detail is boring: the wiki home
is at one fixed path that is the same on every machine. Let each session pick its own
root and nothing ever compounds, which is the whole point.
It deliberately lives outside the config repo, because raw/ fills up with downloaded
PDFs and images and those have no business in something you clone onto every machine.
Measuring what it costs
Everything above adds context, and context is not free, and the way it is not free is counterintuitive enough that I had to build something to see it.
A tool result is paid twice: once as output when it lands, and again as a cache read on every subsequent turn. So its real cost is its size multiplied by the number of turns that follow it. On one real session that turned 300,382 raw tool-result tokens into 83,194,646 amplified ones — a factor of 277.
Three things fall out of that, and all three are the opposite of the obvious move:
- Early context is worth roughly 400× late context. A 3,708-token result landing at the start outranks an 18,601-token one landing near the end.
- Always-loaded surface is the most expensive thing there is — tool schemas, skill bodies, steering files. They are paid from turn one, every turn. Which is an uncomfortable finding for a post about how many skills I have installed.
- Frequency beats size. A poll loop re-reading a 7.5k payload six times costs more than one 40k read.
So ranking by payload size — the obvious approach — is simply wrong, and the scanner ranks by amplified cost instead. It runs as a hook when a session closes, it is Python reading a transcript, and it costs zero model tokens. Backfilling it across 162 real sessions produced 828 findings in 4.7 seconds.
Agents that outlive the wait
The last piece is about what happens when the work outlives the session that started it.
Most planned work is gated on a code review, and a code review is gated on a human being available. A sub-agent ends when it replies. So you dispatch a sub-agent, it does good work, it posts a review, it returns — and when feedback lands the next morning there is nobody holding the context and a fresh agent has to reconstruct everything.
The fix is a durable worker: a long-lived session in its own git worktree that stays alive across the whole review wait and every round of feedback, and that I can talk to directly rather than through the orchestrator. Sub-agents are still right for short, self-contained, ungated work. They are the wrong shape for anything a human has to approve.
The ordering of those three controls is the part worth arguing about, because it is not the order anyone reaches for. The instinct is to cap the number of workers. But every rate limit this machine has ever hit was a session limit or a monthly spend limit — cumulative-usage quotas, not throughput limits. A worker-count cap does not constrain cumulative spend at all; twenty workers just burn the quota twenty times faster. So the budget governor is the primary control and the count ceiling is the weakest of the three.
I want to be honest about the evidence there, because the skills insist on it and it would be strange to drop the habit here. The stagger and the concurrency ceiling are measured. The budget governor is inferred — reasoned from three real quota events plus a proven cost linearity, not from a ramp that ever actually reached a budget wall. The concurrency ramp that produced those numbers spent $2.84 of Haiku, roughly four orders of magnitude below where the real limits fire, so it could not possibly have detected them.
What it actually buys
The honest summary is that none of this makes the agent smarter. It makes it consistent, which is a different and more useful thing. The same investigation happens whether or not I remembered to ask for one. The tests get written before the code because a rule says so and not because I was in the mood. The expensive path gets measured rather than guessed at.
And the failure mode it protects against is not the agent doing something dramatic. It is the quiet one: a plausible answer, delivered confidently, that nobody checked — and then built on.