Adding a post to this repository isn't a complicated procedure. And yet it kept getting re-explained:

Copy an existing post and fill in the front matter, always create ko and en together, same date on both, the body is HTML not markdown and uses the existing posts.css classes, only link to posts that publish before this one, then run npm run build and make sure it passes...

By the third time, two things stand out. Something is always missing — and it's a different something each time.

The real cost isn't typing, it's consistency. Same task, different instructions, different results.

1. Deciding What Becomes a Skill

Not every repetition deserves one. Our tests:

  • Have you done it three times? Twice is coincidence; three is a pattern.
  • Does the procedure have an order? A single question is just a question.
  • Is there a step that's easy to forget? This is the one that matters.

That third test carries the decision. A long procedure whose steps are all self-evident doesn't need a skill. A short one that includes "and you also have to do this" does.

Scoring the borderline cases

Two out of three tests pass more often than you'd like. This is the tiebreaker we use — the third test gets extra weight on purpose.

Question No Sort of Yes ────────────────────────────────────────────────────────────── Done it three or more times? 0 1 2 Do the steps have an order? 0 1 2 Does a missed step surface much later? 0 2 3 Must the result come out the same each time? 0 1 2 ────────────────────────────────────────────────────────────── Total 0–3 Just say it when it comes up Total 4–6 One line in the rules file is enough Total 7+ Freeze it into a skill

"Surfaces much later" is deliberate. A mistake that shows up immediately gets caught immediately. The expensive ones are omissions you find weeks out — like learning a month later that a missing redirect quietly broke an indexed URL.

What we actually froze in this repository:

Add a post ko/en pair · front matter · build verification Add a page both locales · staticPages.js · vercel.json redirects Scheduled batch queue file · per-item commits · PR

The second is the clearest example. Creating a page is easy. But the sitemap list and the redirects have to change with it, and the build doesn't catch either. It gets forgotten every single time.

2. What Goes Inside a Skill

We started out treating skills as "a long prompt, saved." That didn't work. Now each one carries four things.

When to use it

The description is information for choosing. "Add a post" is worse than "add a blog post as a ko/en pair and verify it builds." Saying when not to use it helps more still.

Ordered steps

Number only what genuinely has an order. Numbering order-independent steps creates needless serialization.

1. Copy an existing post to create both locale files 2. Fill in the front matter — identical date on both 3. Write the body (HTML, existing posts.css classes) 4. npm run build — fix until it passes 5. Commit once it passes. Never commit a post that doesn't.

The things that get forgotten

This is why the skill exists at all — the most important section.

- Added or moved a page? Update _data/staticPages.js too. The build will not catch this. - Moved a path? Add a redirect in vercel.json. The old URL is in search indexes; deleting alone isn't enough.

Definition of done

What "finished" means. Here it's a passing npm run build plus a visual check on the things the build can't see.

All four in one file

Put together, that's the skeleton of the "add a post" skill we actually use:

# When to use it — information for choosing Add a blog post as a ko/en pair and verify it builds. Not for editing or deleting existing posts. # Steps — numbered only where order matters 1. Copy an existing post into both locale files 2. Fill in the front matter — identical date on both 3. Write the body (HTML · existing posts.css classes) 4. npm run build # Easy to forget — why this skill exists at all - Added or moved a page? Update _data/staticPages.js too - Moved a path? Add the redirect in vercel.json - Only link to posts that publish before this one # Definition of done - npm run build passes - A post that doesn't pass never gets committed

That length is roughly the ceiling. Past it, what's usually crept in is material that belongs in the rules file.

3. Dividing Skills, Rules Files, and Build Guards

All three shape agent behavior, and where something belongs is genuinely easy to get wrong.

Build guard always active · violation blocks progress → mechanically checkable invariants Rules file always active · violation still proceeds → judgment that applies repository-wide Skill only in one task · applies when invoked → ordered procedures, forgettable steps

The dividing line is scope. "Post bodies are HTML" is true no matter what you're doing, so it belongs in the rules file. "When adding a post, do it in this order" only means something during that task, so it belongs in a skill.

And if a rule is mechanically checkable, it belongs in none of the three — it belongs in the build. That's why ko/en symmetry is a build guard rather than a step in the skill. A skill applies when invoked; a build guard applies even when the skill isn't.

A checkable rule sitting inside a skill is in the wrong place.

Skills guide procedures that are easy to miss; they don't enforce invariants. Anything that must be enforced has to fire even when the skill is bypassed.

Deciding where a new rule goes

Answer these top to bottom and the location falls out. The order matters — higher means a stronger guarantee.

1. Can it be checked mechanically? Yes → Build guard. Stop here. No → question 2 2. Does it only mean something in one task? No → Rules file (judgment that spans the repository) Yes → question 3 3. Is there an order, or a step that's easy to forget? Yes → Skill No → Nowhere. Self-evident things aren't worth writing down.

Plenty of entries in this repository failed at step 1 and still sat in the rules file: ko/en symmetry, link direction between posts, matching date across locales. All three only started holding once they moved into the build. For as long as they were prose, they kept drifting.

The "No" branch at step 3 comes up more than you'd expect — a skill that looked worth writing turns out to hold one obvious line. We deleted those.

4. Mistakes We Made

Skills that copy the rules file

At first we duplicated rules into the skills. Then a rule changed and the two copies disagreed — with no way to tell which was current.

Now skills only point: "front matter fields follow the table in CLAUDE.md." One rule, one place to change it.

Skills that are too large

A "manage the blog" skill ends up covering adding, editing, deleting, and reorganizing. Half of it is irrelevant on any given run, and it stops being clear when to invoke it. One task, one skill works better.

Baking decisions into the skill

Skills should carry how, not what. Put a list of topics inside an "add a post" skill and it stops being a skill — it's a plan. Plans belong somewhere else.

5. What We Deliberately Didn't Freeze

Some procedures repeat and still didn't become skills.

  • One-off work. No reuse, no reason to freeze it.
  • Work where the judgment changes each time. If it's a decision rather than a procedure, a skill gets in the way.
  • Single-step work. Just say it.

The second one is subtle. "What should this post be about" recurs constantly, but the answer must differ every time. Freeze that into a skill and you get the same post repeatedly. Recurring and worth-freezing are not the same property.

When the Skill Exists and Still Gets Ignored

Sometimes a skill is written and simply doesn't take effect. It came down to four cases, each with its own symptom.

Symptom Cause Where to fix it ────────────────────────────────────────────────────────────────── Never invoked at all The description says Put the "when" what, never when into the description Half the steps are One skill covers Split it along irrelevant several tasks task boundaries Behaves differently The skill copied a Delete the copy, from the docs rule; the rule moved point at it instead "Done" means something No definition of done Name the verifying different each run command (here, build)

The first row is by far the most common. A description reading Add a post gives nothing to choose on, so however well the procedure is written, the file never opens. A skill's description isn't a summary of its contents — it's the invocation condition.

The third row is tangled up with repository layout. When the rules are scattered across several places, a skill can't even tell which one to point at. Settling where documents live first removes about half of this problem.

Frequently Asked Questions

How are skills different from slash commands?

In how they get invoked. A slash command is typed by a person; a skill opens on its own when its description matches the work. That makes the description the skill's entire interface. If a person will always start the task anyway, a command is enough. If the agent has to recognize the moment, it needs to be a skill.

How many skills should a repository have?

Overlap matters more than count. If two skills' names don't tell you which to reach for, you already have too many — whatever the number. This repository has three, and their subjects (posts, pages, batches) don't overlap, so choosing costs nothing.

What if a skill never gets invoked?

It's almost always the description. Check that it carries all three of subject (what), timing (when), and exclusion (when not to). If it still doesn't open, the task is probably one a person always initiates — in which case a command is the right shape.

Can a skill contain a script?

If it can, you're usually better off keeping the script and deleting the skill. A fully automated procedure isn't a procedure; it's one command. Skills earn their keep when judgment is interleaved between the steps.

If we have a rules file, why bother with skills?

Scope. A rules file always applies — but always applying also means always being read, occupying context during unrelated work. Put a 20-line procedure needed by one task into the rules file and every other task pays for it. A skill defers that cost to the moment it's needed.

What if the skill keeps changing?

A skill that changes constantly usually has a plan mixed into it. Procedures are stable; plans change every run. Here, everything that varies per batch moved into the scheduled-publishing queue file, leaving the skill with one instruction: read the queue and start from the first unfinished item. We haven't had to edit it since.

6. In Summary

What skills bought us wasn't saved time — it was consistency. The same task now runs in the same order through the same checks.

  • Writing the same explanation a third time is the signal.
  • Freeze only procedures with forgettable steps. Self-evident ones don't need a skill.
  • Rules in the rules file, procedures in skills, checkable things in the build.
  • Skills point at rules instead of copying them. Copies drift.
  • Carry how, not what. Decisions belong in the plan.

If you keep re-explaining the same work, write that explanation carefully once and put it in the repository. What you stop losing isn't keystrokes — it's the results that came out slightly different every time.