Detailed content
🪧 Rule = strong suggestion (non-deterministic)
A rule is a strong suggestion to the model—not a guarantee. It's the “do not enter” sign by the side of the road: most people respect it, but nothing physically stops anyone who decides to enter. Rules are non-deterministic: the model follows them most of the time, but can slip, especially deep into a long conversation.
🌱 New here?
Deterministic = always happens the same way, without relying on judgment. Nondeterministic = depends on the model "deciding" at the time, so it varies. A rule written in the CLAUDE.md is nondeterministic: it’s text that influences, not code that enforces.
💡 When one rule is enough
For preferences and common sense — "prefer tables to paragraphs," "always use a formal tone with clients" — the rule is perfect: cheap, flexible, and easy to adjust. The problem is trusting it where a slip-up is costly.
Why learn
Because knowing that a rule is “soft” calibrates your confidence. You stop treating every limit as unbreakable and save the heavy artillery (hooks) for what truly cannot fail. Understanding this distinction is at the heart of the Guardrails layer.
Key concepts
🔒 Hook = deterministic (always/never)
One hook (hook) is deterministic: it always does or never lets you do it without relying on the model’s judgment. It’s the locked door — no matter how deep into the conversation the OS is, the hook fires the same way. “Never let me send an email with my birth certificate attached” becomes a hook, not a rule.
How to read: the same risky action (red arrow) hits both fences. With the rule (dashed fence), it can slip through; with the hook (solid, locked gate), it’s blocked every time. That’s why what really hurts becomes a hook.
Why learn
Because the rule/hook distinction is the OS’s most important security decision. PII, money, and database writes can’t depend on the model “remembering”—they need a mechanism that always fires. Knowing how to turn a boundary into a hook is what makes the OS safe enough for real use.
Key concepts
📑 Breaking up the bloated CLAUDE.md into rules/
Remember the discipline from Module 2.1 — keep the CLAUDE.md concise? When it starts to bloat with “always do X / never do Y,” it’s time to graduate these lines into a folder rules/ dedicated. The identity stays short; the rules get an organized home in rules/always.md e rules/never.md.
📗 rules/always.md
What the OS should always do.
- ✓"Always convert amounts to CAD."
- ✓"Always cite the policy source."
📕 rules/never.md
What the OS never should do.
- ✗"I never mix personal expenses with business expenses."
- ✗"I never promise anything outside the playbook."
💡 Promote means move, not duplicate
When moving a rule to rules/, remove it from the CLAUDE.md and leave only a pointer there (“see rules/”). Duplicating is the fastest way to create conflicting rules.
Why learn
Because this is how the foundation grows without turning into a mess: the identity stays lean, and the rules become an auditable set. Separating always of never also makes explicit what is “always” — a candidate for becoming a deterministic hook.
Key concepts
⚡ Reflex hooks: block PII on push
The most classic example of a hook is the reflex hook (reflex hook): a mechanism that triggers right away when faced with a dangerous trigger. The author’s example: if you try to upload something with PII to GitHub — Social Security number (SIN), credit card — the reflex blocks immediately and you see “action blocked.”
🌱 New here?
PII (Personal Identifiable Information) is any data that identifies you: CPF/SIN, credit card number, certificates. Push to GitHub = send your files to a remote repository in the cloud. Put the two together: a push with PII can publicly expose sensitive data—exactly what the reflex hook prevents.
🛟 Reflex, not memory
The point of the reflex is that it doesn’t depend on the model remembering. Even if the OS “forgets” the rule deep into a long session, the hook stays on guard. It’s the difference between ask care and ensure care.
Why learn
Because the most costly errors are the silent ones—a PII leak you discover only later. A reflex hook turns “I hope it doesn’t happen” into “it can’t happen.” This is the layer that makes the OS safe for real tasks involving sensitive data.
Key concepts
⚙️ settings.json: ban write commands
The harness comes with a file, ready to use settings.json. That's where you create permission hooks: ask Claude Code to ban write commands — for example, never write to a specific database table — unless there is an explicit override. It adds these commands to a Bash blocklist, and that's it: dangerous writes are prohibited by default.
🌱 New here?
O Bash is the terminal through which the OS runs commands on your computer. The settings.json has a section permissions.deny that refuses certain commands before they run. Override = an exception you deliberately allow. That way, the default is safe, and risk exists only when you decide.
✓ Safe default
- ✓Writing in sensitive tables: denied.
- ✓Destructive Bash commands: on the blocklist.
- ✓You allow access case by case, intentionally.
✗ Without the hook
- ✗One wrong command deep in the context erases data.
- ✗You trust that the model “won’t do it.”
- ✗The mistake only shows up when it’s too late.
Why learn
Because the settings.json is where "never write here" stops being persuasive text and becomes a machine rule. It’s the easiest hook to install and one of the most rewarding: it protects your data from a single careless command.
Key concepts
🔍 PII pre-commit hook
A cousin of the reflex hook is the pre-commit hook: a checker that runs before every commit and gives it one last check. The author’s practice: whenever something is going to be sent to GitHub, the pre-commit checks twice if there's nothing specific to it—PII—in that content. If there is, the commit is blocked.
How to read: every commit goes through the checker (cyan). A clean file goes to GitHub (green); a file with PII is blocked (red) and returned. The backup happens — but only for what’s safe.
Why learn
Because you’ll want to version and back up the OS on GitHub (Track 5), and a backup without safeguards is a leak waiting to happen. The PII pre-commit hook lets you back up with peace of mind: it ensures sensitive data never crosses the boundary—combining with the .gitignore of what’s private.
Key concepts
🧪 Done check: worst mistake → never rule + 1 reflex
The done criteria for this layer are simple and powerful: think of the worst possible mistake your domain and make sure it’s written as a clear never-rule in rules/never.md — and that you have identified at least 1 automatic reflex (hook) for what hurts the most.
✅ The 3-step done check
Name the worst mistake: “what, if it happened, would I be unable to undo or defend?”.
Write it as a clear never-rule in rules/never.md (text, the soft fence).
Reinforce with 1 reflection deterministic (settings.json or pre-commit) — the locked door.
⚠️ The mistake of stopping at the rule
Writing the never-rule and thinking you're done is the trap. A rule is a suggestion; if the worst mistake is irreversible, it requires with a deterministic reflex on top. Rule + reflex = the double fence that actually holds.
Why learn
Because it’s an actionable criterion you can apply to any domain in 5 minutes. It forces the right question ("what must not fail?") and the right-sized answer (text for everything else, a hook for the irreversible). It’s exactly the done-check that the /os-coach is charged in Track 4.
Key concepts
⚡ Practical: settings.json with write deny rules
Time to install a real locked door. Below is a .claude/settings.json copy-run: it denies Bash write/destructive commands (permission hook) and adds a PreToolUse hook that blocks database writes unless overridden. Change only the sections between <brackets>.
🎯 Objective
Leave this section with a real deterministic hook: the OS physically rejects dangerous write commands, without relying on you to “remember” the rule.
Save to .claude/settings.json — copy-run
json{
"permissions": {
"deny": [
"Bash(rm:*)",
"Bash(git push:*)",
"Bash(psql:*)",
"Bash(sqlite3:*)",
"Bash(<sua-cli> write:*)",
"Bash(<sua-cli> delete:*)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -qiE '(INSERT|UPDATE|DELETE|DROP|TRUNCATE).*<tabela_sensivel>' && [ \"$ALLOW_DB_WRITE\" != \"1\" ] && { echo 'Escrita no banco bloqueada (gancho). Use ALLOW_DB_WRITE=1 para override.' >&2; exit 2; } || exit 0"
}
]
}
]
}
}
✔️ How to verify
- 1.Ask the OS to run a git push or one rm — should be refused through the list deny.
- 2.Ask for a command that writes to the <sensitive_table> — the PreToolUse hook must block it with the message (exit 2).
- 3.Repeat with ALLOW_DB_WRITE=1 in the environment — it now passes (explicit override working).
- 4.One SELECT (read) is NOT blocked—the hook targets writing only.
💡 Why this is a hook, not a rule
Nothing here depends on the model "deciding" to obey: the deny e o exit 2 from the hook is code that runs before for the command to run. It’s the locked door from Topic 2, now in a file. Illustrative example — adjust the commands and pattern to your harness and database.
Why learn
Because it turns all the theory about fences into real protection in minutes. With this file, you already have the “1 reflex” from the Topic 7 done-check—and the foundation ready for the production OSs in Track 5, where money and sensitive data make this mandatory.
Key concepts
✅ Module summary
You’ve completed the OS foundation!
With Identity, Substrate, and Fences ready, the next track provides capacity: Skills, Tools, and Agents. → Track 3 · Technique II 🤖