If you set up a CLAUDE.md and rules after the last video, you probably noticed something annoying: Claude still doesn't do anything with that foundation on its own. You ask for a PR summary, and you're typing out the same three paragraphs of instructions you typed last week. You push code, CI fails on a lint error, and you're back in the chat pasting the error and explaining — again — how your project formats Go code.
Every one of those re-explanations costs tokens. On a Claude Pro subscription, that's not an abstract problem: it's your usage window burning down on context Claude should already have. CLAUDE.md fixed what Claude knows. It didn't fix what Claude does with it.
That's what skills and hooks are for. Skills let you point instead of re-prompting. Hooks enforce things deterministically, outside the model entirely — no tokens spent at all.
New to this series? Start with CLAUDE.md & Rules before Skills, Hooks or Agents — everything below builds on that foundation.
Quick recap: the foundation
In the previous video I set up CLAUDE.md and .cursor-style rules for PortfolioPulse, my Go service that snapshots Trading212 portfolio data into Redis and Airtable. The point of that layer was context: project structure, conventions, what not to touch. Claude stopped guessing.
But context is passive. It sits there until you write a prompt that activates it. The next layer is active: reusable workflows (skills) and automatic enforcement (hooks).
Skills: point, don't re-prompt
A skill is a folder with a SKILL.md file — instructions, optionally with scripts and reference files — that Claude Code loads when it's relevant. The key mechanic is progressive disclosure: Claude only sees each skill's name and description at first (roughly a hundred tokens), and pulls in the full instructions only when the task matches. You can host dozens of skills without bloating your context window.
There are two ways to get them.
Installing from a marketplace
The fastest path is installing existing skills as plugins. In the video I install from a marketplace — the same flow works for any published skill collection:
/plugin marketplace add <owner/repo>
/plugin install <skill-name>@<marketplace>
Upstash — which PortfolioPulse already uses for Redis — publishes skills this way, so Claude gets vendor-maintained knowledge about the tool instead of my paraphrased version of the docs. One install, and I never explain Upstash Redis semantics in a prompt again.
One caution that bears repeating: skills can execute code in Claude's environment. Read the SKILL.md and any bundled scripts before installing anything. Trust the source or don't install it.
Creating a custom skill
Marketplace skills cover tools. Your workflows need custom skills. PortfolioPulse now has three — pr-summary, airtable (the field schema and infrastructure rules), and ddd-go (my Go domain-driven design conventions). The live example in the video is the PR-summary skill:
# PR Summary Skill
Generate a structured summary of all changes on the current
branch relative to main, suitable for a pull request
description or a `summary.md` file.
## Steps
1. Run `git log main..HEAD --oneline` to list commits
2. Run `git diff main..HEAD --stat` to see which files changed
3. Run `git diff main..HEAD` to read the full diff
4. Analyse the diff and produce a summary
## Output Format
Write the summary to `summary.md` in the repo root, then
print it to the user:
- What changed — bullet per logical change group
- Why — short paragraph, inferred from commits and context
Before this skill existed, getting that output meant a paragraph of instructions every single time. Now the prompt is: "summarize this PR." Claude reads the changes so I don't have to — and the instructions live in version control, not in my chat history.
Referencing skills from your rules
This is the part that ties the two videos together. Your rules file can point at skills directly — "for PR reviews, use the pr-summary skill" — so the foundation layer routes to the workflow layer automatically. You're not even typing the short prompt anymore; the rules dispatch for you. That's the whole thesis in one move: the layers compose.
Hooks: enforcement without tokens
Skills still run through the model. Hooks don't — and that's their entire value.
A hook is a shell command that Claude Code runs deterministically at lifecycle events: after a file edit, before a commit, when a session stops. The model doesn't decide whether to run it. It just runs. Which means the things you'd otherwise nag Claude about — lint, build, commit-message format — happen every time, at zero token cost.
For PortfolioPulse I wired up five scripts in .claude/hooks/:
-
go-lint-check.sh— a PreToolUse hook that interceptsgit commitcommands and runsgolangci-lintfirst. Lint fails → the commit is blocked and the failure output lands in Claude's context, so it fixes the issues before committing. Broken code physically cannot enter history. -
go-fmt-autofix.sh— formatting fixed automatically on edit, never discussed. -
go-build-check.sh—go build ./...gates changes so nothing broken sits around. -
commit-msg-check.sh— parses the commit subject line (including heredoc-style commit commands) and enforces my message convention. No more "please rewrite that commit message" follow-ups. -
go-prepush-check.sh— the last gate before anything leaves the machine.
The pattern all of them share: read the tool input as JSON from stdin, check whether this is the event they care about (e.g. the Bash command starts with git commit), and exit non-zero to block with feedback:
#!/usr/bin/env bash
# PreToolUse — Bash (git commit *)
# Blocks the commit if golangci-lint finds issues.
set -euo pipefail
INPUT=$(cat)
CMD=$(echo "$INPUT" | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('tool_input', {}).get('command', ''))
" 2>/dev/null || true)
# Only run on git commit commands.
if [[ "$CMD" != "git commit"* ]]; then
exit 0
fi
cd "$CLAUDE_PROJECT_DIR"
OUTPUT=$(golangci-lint run ./... 2>&1) || {
echo "golangci-lint failed — fix before committing:"
echo "$OUTPUT"
exit 2
}
exit 0
The demo that sells it in the video: a CI lint failure that would normally trigger the paste-error-explain-wait loop gets caught and fixed through the hook — the failure output lands in Claude's context automatically, Claude patches it, the hook re-runs green. Zero re-prompting. The feedback loop that used to involve me is now a closed circuit between the linter and the model.
The mental model that finally clicked for me: use the model for judgment, use hooks for rules. If something must happen 100% of the time, it shouldn't be a prompt — prompts are probabilistic. Hooks are not.
Skills for pointing, hooks for enforcing
Here's where the stack stands after two videos:
| Layer | Job | Cost |
|---|---|---|
| CLAUDE.md + Rules | What Claude knows | Loaded once per session |
| Skills | Workflows you point at | Loaded only when relevant |
| Hooks | Rules enforced outside the model | Zero tokens |
The foundation without this layer is knowledge that you still have to activate by hand every session. This layer without the foundation is workflows firing with no project context. Together, they're the setup where you stop being Claude's context-delivery service and start just... asking for things.
The verdict
Two videos in, the pattern is clear: every layer exists to remove a category of repeated work. CLAUDE.md removed re-explaining the project. Skills removed re-explaining workflows. Hooks removed the checks I was manually policing. None of these makes Claude smarter — they make you stop paying the same context tax every session, in tokens and in patience.
If you take one thing from this: audit your last ten prompts. Anything you've typed twice belongs in a skill. Anything that must happen 100% of the time belongs in a hook — prompts are probabilistic, hooks are not. The prompt is only for the part that's actually new.
Next in the series: MCP servers and subagents — giving Claude external tools and delegation on top of this stack.
Watch the full walkthrough with the live demos — the marketplace install, the PR-summary skill, and the lint failure fixed without a single re-prompt:
The whole setup is in the repo: Mozes721/PortfolioPulse
Part 1 of this series: CLAUDE.md & Rules — Before Skills, Hooks, or Agents
Docs: Claude Code Best Practices



Top comments (0)