The rule I settled on: automate judgment with a skill, automate a fixed sequence with a script. Get it backwards and one of two things breaks. Either you chain a task that needed thinking, or you ask for thinking on a task that needed a locked chain.
I run both every day in Claude Code. They feel similar from the outside, a slash command or a shell command that saves you typing. They are not the same tool, and the failure modes are opposite.
The difference in one table
| Skills | Scripts | |
|---|---|---|
| What it is | A framework that guides the AI’s judgment | A fixed chain that runs the same every time |
| When thinking happens | During the run, on this specific input | Once, when you wrote it |
| Output | Varies with context | Identical every run |
| Fails by | Bad judgment | A step that no longer fits reality |
A skill like /think is a set of guardrails. It doesn’t run fixed steps. It tells Claude to slow down, name the real problem, check the assumptions, then recommend a path. The output is different every time because the input is. It guides thinking without replacing it, and other skills route through it at any ambiguous decision point.
A script is the opposite bargain. When I run ./deploy.sh, the same sequence fires every time: preflight checks, build, sync, verify. No judgment, no adaptation. I don’t want Claude reasoning about my deploy order at 2am. I want the chain to run exactly as written, or stop.
The incident that set the rule
Scripts fail in a specific, quiet way: the steps are locked, so when the world changes shape underneath them, they keep running and produce garbage.
My cache.sh warms the production cache after a deploy by reading every URL out of the sitemap. It worked for months. Then I moved the front end to Astro, and Astro emits its sitemap as one minified line instead of one <loc> per line. My parse was line-based. It found exactly one URL, warmed one page, and reported success. The fix (commit 824fa50, June 2026) was a one-line switch to grep -o so it reads the whole line. The point is what the script did before that fix: nothing alerted, because a script has no judgment. It ran precisely what I told it to, against an input that no longer matched the instruction.
A skill would have adapted to the new format. But I would never put the deploy warm-up behind a skill, because I don’t want that step to be creative. I want it identical every time. The right move was not “make it a skill.” It was “keep it a script, and fix the chain.”
The two ways it goes wrong
Script when you needed a skill: you turn code review into a linter. The linter passes. The code is still wrong across three files in a way no single-file check catches. You needed judgment, and you automated a checklist.
Skill when you needed a script: you deploy by hand every time, thinking through the steps. One day you skip the build. Production breaks. You needed a locked chain, and you left it to memory.
Where each one lives in the stack
Skills and scripts are not the whole picture. They are the top two layers of how I keep AI-assisted work honest:
/think, /audit, /remediation. Adapt to the specific input.That third layer exists because I learned the hard way that guidance is not a guarantee. A skill made the AI more likely to follow my rules. It still shipped 104 policy violations into a codebase I thought was clean until a hard gate caught them.
The rule
Automate judgment with skills. Automate sequences with scripts. Gate the result with enforcement.
If the task needs to adapt to context, build a skill: a framework that guides thinking without doing it for you. If the task is the same steps every time, build a script: a chain that removes the chance you forget one. And if the cost of getting it wrong is real, do not trust either one to police itself. Put a gate after it.
Skills keep you fluid. Scripts keep you consistent. Knowing which the task needs is most of the job.
Related: