---
name: claude-gates-hooks-skills
description: "Hamza Khalid's beginner kit for Claude Code rules that stick: a rule sorter that splits CLAUDE.md into gates, hooks, skills and facts, a ready review-draft skill, a notification hook for Mac and Windows, a hard folder gate and a smart 'done means evidence' gate, a one-paste install and a test checklist. Use when the user keeps repeating rules to Claude, wants to set up skills, hooks or permission deny rules, or asks which one a rule belongs in."
metadata:
author: "Hamza Khalid"
source: "https://smart-scabiosa-77d.notion.site/Claude-Gate-Vs-Skills-Vs-Hooks-Kit-3f3816ad5f7180d787aada0902229193"
newsletter: "https://www.aiinpublic.com"
title: "Claude Gate Vs Skills Vs Hooks Kit"
post: "https://www.aiinpublic.com/p/claude-code-gates-vs-hooks-vs-skills"
note: "Copied from the creator's free page. Removed only page furniture: image placeholders, empty callouts, coffee/share call-outs, lines pointing at embedded posts that did not carry over, and the closing PS."
---
# Claude Gate Vs Skills Vs Hooks Kit
#### One skill, one hook, and two gates for Claude Code, ready to paste. For anyone tired of telling Claude the same rule again and again.
---
**Introduction**
Most people put every rule in one place: CLAUDE.md, or the chat. Claude reads it, follows it most of the time, and sometimes doesn't.
You saw the fix in the issue. Skills teach Claude a task. Hooks run something every time. Gates stop Claude from doing something.
This pack gives you all of it ready to paste: one skill, one hook, two gates, a one-paste install, and prompts to build your own.
Inside: 1 rule sorter, 1 skill, 1 hook, 2 gates, 1 one-paste install, 3 "build your own" prompts, and a test checklist.
**Read time:** 6 minutes. **Time to set up:** 15 minutes.
---
### Why I Built This
Anthropic's own Claude Code docs say a rule written in CLAUDE.md or a skill is "a request, not a guarantee." That one line explains most of the "why did Claude do that?" moments.
The fix already exists inside Claude Code. Most people never set it up, because the docs are written for developers.
So I packed the setup I'd want on day one, in plain English, with nothing to write from scratch. You copy, you paste, you test.
One caveat I'll repeat inside: a gate only blocks what you tell it to block. Test every gate once by trying to break it.
---
**Before You Start - Quick Checklist**
- [ ] You've read the issue and know what skills, hooks, and gates are
- [ ] Claude Code is installed and you've signed in
- [ ] You have a project folder, like `my-claude-setup`
- [ ] You know you're inside Claude Code when you see Claude's typing box, not a line ending in `%`
- [ ] You have 15 minutes free
---
### What's Inside
**1. The Rule Sorter:** One prompt that sorts every rule you already have into skill, hook, gate, or keep.
**2. The Skill:** A ready review skill, plus a prompt to build your own.
**3. The Hook:** The alert hook for Mac and Windows, plus one variation.
**4. The Two Gates:** A hard gate that locks a folder, and a smart gate that checks Claude's work before it says "done."
**5. The One-Paste Install:** Everything above in one prompt, for Mac and Windows.
**6. The Test Checklist:** How to prove each layer works, and what to do if it doesn't.
---
### Who This Is For
- Beginners who just installed Claude Code
- Writers and creators who want Claude to stop touching finished work
- Freelancers who need client files kept separate
- Anyone whose CLAUDE.md keeps growing and still gets ignored
If you haven't read the issue yet, start there, then come back here.
---
### How to Use It
**Step 1 - Duplicate this page:** Hit the ••• menu top right → Duplicate. Now it's yours to edit.
**Step 2 - Open Claude Code:** In the terminal, type `cd my-claude-setup`, press Enter, then type `claude` and press Enter.
**Step 3 - Fast way:** Go to Section 5 and paste the One-Paste Install for your computer. Done.
**Step 4 - Slow way:** Go through Sections 2 to 4 one at a time, if you want to understand each layer.
**Step 5 - Test it:** Section 6. Test every layer once.
**Step 6 - Sort your old rules:** Section 1. Run the Rule Sorter on your CLAUDE.md.
**Where to paste the prompts:** Inside Claude Code, in Claude's typing box. Never in the plain terminal.
**After any change to settings:** Restart Claude Code. Type `/exit` and press Enter, then type `claude` and press Enter.
---
### 1. THE RULE SORTER
**What this does:** Reads your CLAUDE.md and tells you where each rule really belongs. Run it once you have the three layers set up.
```text
Read my CLAUDE.md file. Sort every rule into one of four groups:
1. GATE: anything that must never happen. Write the matching permission deny rule for .claude/settings.json.
2. HOOK: anything that must happen every time at a set moment, with no judgment. Name the hook event it belongs to.
3. SKILL: anything that needs judgment or is a multi-step procedure. Suggest a skill name and a one-line description.
4. KEEP: facts about the project that Claude should always know.
Show the result as a table with columns: Rule, Group, What to write.
Do not change any files yet. Wait for my approval.
```
**Variation: No CLAUDE.md yet**
```text
I don't have a CLAUDE.md file yet. Ask me 5 short questions about how I work and what Claude keeps getting wrong. Then sort my answers into GATE, HOOK, SKILL, and KEEP, using the same table.
```
---
### 2. THE SKILL
**What this does:** Saves a checklist Claude uses when you ask it to review your writing. Type `/review-draft`, or just say "review my post."
**Check it worked:** Type `/skills` and look for **review-draft**.
**Prompt 1: Install the review skill**
```text
Create a skill file at .claude/skills/review-draft/SKILL.md with exactly this content:
---
name: review-draft
description: Review a written draft before it is published. Use when the user asks to review, check, edit, or polish a newsletter, post, email, or article.
---
Review the draft in this order:
1. Find every claim that needs a source. List each one with the source it needs.
2. Flag any sentence over 25 words. Suggest a shorter version.
3. Flag any placeholder text such as TODO, TBD, [INSERT], or lorem ipsum.
4. Check that every link is written as a full URL.
5. Report what you found as a numbered list. Do not rewrite the draft unless asked.
```
**Prompt 2: Build your own skill**
```text
I keep giving you the same instructions every time I ask for [THE TASK, e.g. a LinkedIn post]:
[PASTE THE INSTRUCTIONS YOU KEEP REPEATING]
Turn this into a Claude Code skill:
1. Create .claude/skills/[SHORT-NAME]/SKILL.md
2. Write a description that uses the words I would naturally type when asking for this.
3. Write the instructions as a numbered list.
Show me the file before saving it.
```
**Tip:** The description line decides when Claude uses the skill on its own. Write it with the exact words you'd use when asking.
---
### 3. THE HOOK
**What this does:** Shows an alert on your screen when Claude needs you, so you can stop checking the window.
**Mac users, do this first:** In a plain Terminal window, paste `osascript -e 'display notification "Test" with title "Claude Code"'` and press Enter. No alert? Open **System Settings** → **Notifications** → **Script Editor** → turn on **Allow Notifications**.
**Check it worked:** Restart Claude Code, then type `/hooks` and look for your hook under **Notifications**.
**Prompt 1: The alert hook (Mac)**
```text
Add a Notification hook to .claude/settings.json in this project. If the file already exists, keep everything in it and add this inside "hooks":
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
Show me the final file before saving it.
```
**Prompt 1: The alert hook (Windows)**
```text
Add a Notification hook to .claude/settings.json in this project. If the file already exists, keep everything in it and add this inside "hooks":
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
]
Show me the final file before saving it.
```
**Variation: Only alert when Claude needs your approval**
```text
In .claude/settings.json, change the Notification hook's "matcher" from "" to "permission_prompt". Keep everything else the same. Show me the final file before saving it.
```
With this change, you only get an alert when Claude is waiting for your "yes," not when it has simply finished replying.
---
### 4. THE TWO GATES
**What this does:** Gate 1 locks things Claude must never touch. Gate 2 stops Claude from saying "done" without proof.
**Check it worked:** Restart Claude Code. Type `/permissions` to see Gate 1. Type `/hooks` and look under **Stop** to see Gate 2.
**Gate 1: The Hard Gate**
Use when: something must never happen, no matter what.
**Prompt 1: Lock your published folder**
```text
Add these permission deny rules to .claude/settings.json in this project. Keep everything else in the file exactly as it is.
"permissions": {
"deny": [
"Read(./.env)",
"Edit(./published/**)",
"Bash(rm *)"
]
}
Show me the final file before saving it.
```
What each rule does:
- `Read(./.env)` keeps Claude out of the file where apps store passwords.
- `Edit(./published/**)` locks everything in your `published` folder.
- `Bash(rm *)` blocks the normal delete command.
**Variation: Lock a client's folder**
```text
Add "Read(./clients/[CLIENT NAME]/**)" and "Edit(./clients/[CLIENT NAME]/**)" to the deny list in .claude/settings.json. Keep everything else the same. Show me the final file before saving it.
```
**Variation: Never let Claude push code**
```text
Add "Bash(git push *)" to the deny list in .claude/settings.json. Keep everything else the same. Show me the final file before saving it.
```
---
**Gate 2: The Smart Gate**
Use when: you want proof before Claude says a job is done.
**Prompt 1: The proof check**
```text
Add a Stop hook to .claude/settings.json in this project. Keep everything else exactly as it is.
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "You are a strict reviewer. Here is the data for this turn, including Claude's last message: $ARGUMENTS. Block the finish if the last message says work is done, checked, verified, or passed without real evidence such as a file name, a count, a line number, or a test result. Also block it if the last message contains placeholder text such as TODO, TBD, [INSERT], or lorem ipsum. If you block, respond with {\"ok\": false, \"reason\": \"name exactly what is missing\"}. Otherwise respond with {\"ok\": true}."
}
]
}
]
Show me the final file before saving it.
```
**Prompt 2: Build your own gate**
```text
Claude just did something that must never happen again: [DESCRIBE WHAT HAPPENED].
Turn this into a gate:
1. Tell me if it should be a hard gate (a deny rule) or a smart gate (a Stop hook check).
2. Write the exact rule or hook to add to .claude/settings.json.
3. Tell me one way it could still slip through, and how to close that gap.
Do not edit any files. Show me the changes first.
```
---
### 5. THE ONE-PASTE INSTALL
**What this does:** Sets up the skill, the hook, and both gates in one go. Use the version for your computer.
**After it finishes:** Restart Claude Code, then run the Test Checklist in Section 6.
**One-Paste Install (Mac)**
```text
Set up this project with three things. Show me every file before saving it.
1. Create .claude/skills/review-draft/SKILL.md with exactly this content:
---
name: review-draft
description: Review a written draft before it is published. Use when the user asks to review, check, edit, or polish a newsletter, post, email, or article.
---
Review the draft in this order:
1. Find every claim that needs a source. List each one with the source it needs.
2. Flag any sentence over 25 words. Suggest a shorter version.
3. Flag any placeholder text such as TODO, TBD, [INSERT], or lorem ipsum.
4. Check that every link is written as a full URL.
5. Report what you found as a numbered list. Do not rewrite the draft unless asked.
2. Create a folder called published with a file called live-post.md that says "This post is live."
3. Create .claude/settings.json with exactly this content. If the file already exists, merge this in and keep everything else:
{
"permissions": {
"deny": [
"Read(./.env)",
"Edit(./published/**)",
"Bash(rm *)"
]
},
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "You are a strict reviewer. Here is the data for this turn, including Claude's last message: $ARGUMENTS. Block the finish if the last message says work is done, checked, verified, or passed without real evidence such as a file name, a count, a line number, or a test result. Also block it if the last message contains placeholder text such as TODO, TBD, [INSERT], or lorem ipsum. If you block, respond with {\"ok\": false, \"reason\": \"name exactly what is missing\"}. Otherwise respond with {\"ok\": true}."
}
]
}
]
}
}
```
**One-Paste Install (Windows)**
```text
Set up this project with three things. Show me every file before saving it.
1. Create .claude/skills/review-draft/SKILL.md with exactly this content:
---
name: review-draft
description: Review a written draft before it is published. Use when the user asks to review, check, edit, or polish a newsletter, post, email, or article.
---
Review the draft in this order:
1. Find every claim that needs a source. List each one with the source it needs.
2. Flag any sentence over 25 words. Suggest a shorter version.
3. Flag any placeholder text such as TODO, TBD, [INSERT], or lorem ipsum.
4. Check that every link is written as a full URL.
5. Report what you found as a numbered list. Do not rewrite the draft unless asked.
2. Create a folder called published with a file called live-post.md that says "This post is live."
3. Create .claude/settings.json with exactly this content. If the file already exists, merge this in and keep everything else:
{
"permissions": {
"deny": [
"Read(./.env)",
"Edit(./published/**)",
"Bash(rm *)"
]
},
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "You are a strict reviewer. Here is the data for this turn, including Claude's last message: $ARGUMENTS. Block the finish if the last message says work is done, checked, verified, or passed without real evidence such as a file name, a count, a line number, or a test result. Also block it if the last message contains placeholder text such as TODO, TBD, [INSERT], or lorem ipsum. If you block, respond with {\"ok\": false, \"reason\": \"name exactly what is missing\"}. Otherwise respond with {\"ok\": true}."
}
]
}
]
}
}
```
---
### 6. THE TEST CHECKLIST
**What this does:** Proves each layer works. A layer you never tested is a layer you can't trust.
**Test the Skill**
- [ ] Type `/skills` and see **review-draft** in the list
- [ ] Type `/review-draft`, paste some writing, and get a numbered list back
**Test the Hook**
- [ ] Type `/hooks` and see your hook under **Notification**
- [ ] Ask Claude "Say hello," switch to another window, and wait about one minute
- [ ] An alert appears: "Claude Code needs your attention"
**Test Gate 1**
- [ ] Type `/permissions` and see all three deny rules
- [ ] Ask Claude: "Change published/live-post.md to say This post is updated."
- [ ] Claude Code refuses
**Test Gate 2**
- [ ] Type `/hooks` and see your hook under **Stop**
- [ ] Ask Claude: "Create a file called checklist.md with three items for launching a newsletter, then tell me it's done and checked."
- [ ] If Claude says "done" without naming the file and the item count, it gets sent back to work
**If Something Doesn't Work**
| What you see | What to do |
| --- | --- |
| `zsh: command not found` when you paste a prompt | You're in the plain terminal. Type `claude`, press Enter, then paste again |
| The hook isn't in `/hooks` | Restart Claude Code: `/exit`, then `claude` |
| No alert on Mac | Turn on **Script Editor** in System Settings → Notifications |
| No alert on Windows | Check your taskbar. The pop-up can open behind other windows |
| A gate doesn't block | Ask Claude: "Show me my .claude/settings.json file." Check the rule is in the deny list |
| Claude keeps getting sent back by Gate 2 | Make your check something Claude can actually pass. Claude Code stops the loop after eight tries |
---
**You're Done - Checklist**
- [ ] The review skill shows up in `/skills`
- [ ] You got the alert at least once
- [ ] Claude Code refused to change your published folder
- [ ] Gate 2 sent Claude back at least once
- [ ] You ran the Rule Sorter on your CLAUDE.md
- [ ] You built one skill or gate of your own
---
**Common Mistakes (Avoid These)**
- [ ] Pasting prompts into the plain terminal instead of Claude Code
- [ ] Forgetting to restart Claude Code after changing settings
- [ ] Leaving the [square brackets] in the "build your own" prompts
- [ ] Turning every rule into a gate. Rules that need thinking belong in skills
- [ ] Trusting a gate you never tested
- [ ] Thinking `Bash(rm *)` blocks every kind of delete. It only blocks the normal `rm` command
---
### Closing Note
Writing a rule was never the hard part. Most people have written the same rule five times.
Putting it where Claude can't skip it is the hard part, and now you have it: a skill for judgment, a hook that runs every time, and two gates Claude can't talk its way past.
Set up one layer today. Test it. Then add the next one tomorrow.
**Make Yourself Irreplaceable with AI. LLMs don't think; you do.**
We tested it in public. Now go use it in private.
https://substack.com/@humzakhalid
-Hamza 💙