The problem
I kept retyping the same prompt, slightly worse each time.
Writing an article, filing a ticket, cutting a release, reviewing a spec, prepping a talk — each is a task I do repeatedly, with a shape I've refined over dozens of attempts. And every time, that refinement lived nowhere. It was in the last good prompt, in a chat window I'd closed, or in my head on a good day.
So the quality of my work with an AI depended on whether I happened to remember the version of the instructions that worked. That's not a workflow, that's a habit with extra steps.
The deeper problem: I had no way to improve. When a prompt produced a bad result there was nothing to fix — no artifact, no diff, no history. I'd just rephrase and try again. You can't iterate on something you don't keep.
Why I built it
Treat the workflow as code.
Every repeatable task becomes a skill: a named file of instructions, checked into a repo, with a version and a changelog. When a skill produces a bad result, I fix the skill — and that fix is now the default, on every machine, forever. The improvement compounds instead of evaporating.
Everything else follows from that reframing. A workflow you can roll back. A workflow you can review in a diff. A workflow that follows you to a new laptop because it's a git clone, not a folder of notes you meant to sync.
Kaiju is private, and not because the approach is secret — that's what I write and speak about. It's because the contents are personal and, in places, my employer's: how my team files tickets, which internal systems things route to. A public version would have to be generic, and a generic version would be useless to me. The system is worth sharing; my particular configuration of it isn't.
How it works
Skills are grouped by domain — engineering, content, product, knowledge, and a few more — and each is a plain markdown file: a name, a description of when to reach for it, and the instructions. An installer flattens the whole tree into place, so the folder structure is for humans and the AI never sees it.
Here is a real one, start to finish.
---name: add-retro1description: "Add a note to the retro file for the next retrospective. Use when the user mentions retro, wants to note something for the retro, or says 'add retro'."--- # Add Retro 2## When to Use - User says `/add-retro <note>` or mentions adding a retro item- User wants to log something for the next retrospective 3## Workflow ### Step 1: Get the Note### Step 2: Determine Category### Step 3: Read and Update the File 1. Read `Work/Retros.md`.2. Find the most recent `## YYYY-MM-DD` section.3. If none exists for today, create one.4. Append the note under the right subsection. 4### Step 4: Confirm > Added to **[Category]** in retro for [date]: "[note]"- 1The description is the whole retrieval mechanism
- At rest, this line is the only part of the skill the model can see. It has to say what the skill does and — critically — the phrases that should summon it. A vague description is a skill that never fires.
- 2Triggers, restated for the human
- The same information again, for me. Six months later I am also someone who needs to be reminded this exists.
- 3A linear procedure, not a personality
- Numbered steps with one job each. This is the line between a skill and an agent: a skill is a reactive, linear workflow. If it needs parallelism or its own context, it is an agent — and it almost never needs to be.
- 4A defined endpoint
- Skills terminate. The last step says what "done" looks like and what to report. Anything longer — templates, palettes, reference data — moves to a references/ folder beside this file, so the skill stays short enough that the model actually reads all of it.
Two rules do most of the work.
Skill by default; agent only when you must. A skill is reactive, triggered by matching a description, with a linear workflow and a clear endpoint. An agent is a separate instance with its own context. Agents are tempting and almost always wrong — you reach for one only when the work genuinely needs parallelism, heavy context isolation, or a constrained tool allowlist. Otherwise it's a skill. Having that rule written down has stopped me building half a dozen agents I didn't need.
Keep the skill short; push the data out. Instructions in the skill file, everything else — palettes, templates, reference data, scripts — in a references/ folder beside it. A skill that inlines its own data grows until nobody reads it, including the model.
Prior art is credited, not laundered. Several clusters are adapted from other people's public work, and the README says so by name.
The skills are the nouns. The interesting part is the verbs — the chains I actually run back to back, where one skill's output is the next one's input. This is the real argument for keeping each one small and separate: small pieces compose, big ones don't.
Article
An idea becomes a published, illustrated, cross-posted, promoted post.
Product
Research becomes tracked work. The last step dispatches to whichever tracker the project uses.
Knowledge
Anything I read, watch, or half-think gets captured, routed, and eventually groomed.
Work
Small daily logs compound into the artifacts I need once a year.
Results
- 76 skills across 8 domains; version 0.34, 125 commits.
- Everything on this page — the articles, the talks, the projects — is produced through it.
That last point is the actual result. Kaiju isn't a side project; it's the thing that makes the side projects possible at the rate they happen. And it maintains itself: the skill that adds skills is a skill.
- add-skill
A skill that writes skills
- install.sh
Flattens the tree into place
- ~/.claude/skills
Every machine, same state
- Claude Code
Invokes it by description
- The work
Articles, tickets, this page
A bad result is a bug in the skill. Fix the file, and the fix is the default — on every machine, forever.
What I'd do differently
I lost 140,000 words to the wrong file format. For months, my default for writing a report was a self-contained HTML page. It looked great. It was also, inside a knowledge vault, dark matter — no search, no backlinks, no graph. About 11% of everything I'd written was unfindable, including by me. The fix was to make markdown the default and demote HTML to an export path, then write a converter and migrate all 48 existing documents. The lesson isn't about HTML. It's that a format decision made for how something looks on the day can quietly destroy its value for years.
My own installer silently ignored my edits. The install script skips an existing skill file if it differs, unless you force it. So for a while, editing a skill did not deploy it — I'd change something, see no effect, and assume the model was being stubborn. It was me. The most expensive bugs in a personal tooling system are the ones where the system lies to you quietly and you blame something else.
The README says 45 skills. There are 75. It's a small thing and it's the honest cost of moving fast on a repo with no reviewer. There's also an agents/ directory documented in the README that is, to this day, completely empty. When you're the only reader, documentation rots faster, not slower — nobody is going to notice for you.
A skill I shipped wasn't self-contained. It documented components whose CSS only existed in my vault, so in a fresh one it rendered as a grey box. I'd tested it in the only environment where it could possibly work. That's the classic library-author mistake, and it turns out you can make it in a repo with exactly one user.