Makes Claude actually follow your rules.
You tell Claude "never push to main." Claude agrees. Five minutes later, Claude pushes to main.
The memory system is passive — Claude writes rules down but doesn't actively check them. Hooks exist but require manual regex setup. There's no way to say "remember this" and have it actually stick.
obey is a Claude Code plugin that stores your rules, injects them into every session, and actively blocks violations.
/remember never push to main
# → Rule saved (global, hook-enforced)
# → Claude is now blocked from running "git push origin main"
/remember always explain your reasoning before writing code
# → Rule saved (global, instruction)
# → Injected at the start of every session as a reminder
/remember never use .unwrap() --rust
# → Rule saved (Rust projects only, blocks .unwrap() in code)That's it. Rules persist across sessions, survive context compaction, and get actively enforced.
You say: "/remember never force push"
│
obey evaluates the rule:
├── Scope: global (applies everywhere)
├── Mechanism: hook (can be blocked by code)
├── Pattern: git push --force
└── Saved to ~/.config/obey/global-rules.json
│
Next session starts:
├── SessionStart hook fires
├── All rules injected into Claude's context
└── Claude sees: "RULE: Never force push"
│
Claude tries: git push --force
├── PreToolUse hook fires
├── Pattern matches → BLOCKED
├── Claude sees: "Rule violated: Never force push"
└── Claude adjusts behavior
/plugin marketplace add https://github.com/Lexxes-Projects/lexxes-plugins.git
/plugin install obey@lexxes-plugins
claude --plugin-dir /path/to/obey
jq— auto-installed on first run (via apt, brew, choco, pacman, or dnf)
Save a persistent rule.
/remember never push to main # Auto-detected as global, hook-enforced
/remember prefer functional style # Auto-detected as global, instruction
/remember never use console.log --node # Node.js projects only
/remember always run cargo clippy --rust # Rust projects only
/remember this project uses port 3000 --local # This project onlyFlags:
--global— applies to all projects (default for general rules)--local/--project— only this project--rust/--node/--python/--go/--java— only projects with that stack
Two enforcement types:
- hook — actively blocks violations (e.g., blocks
git push origin main) - instruction — injected as reminder at session start AND right before the relevant tool is used (e.g., "explain reasoning before writing code" reminds you every time Claude is about to Write/Edit)
- both — blocked AND reminded
Show all active rules.
/rules # Show all rules
/rules --global # Global rules only
/rules --local # Project rules only
/rules --stack # Stack-specific rules onlyRemove a rule.
/forget 17741838840474 # Remove by ID (shown in /rules output)
/forget force push # Remove by keyword search| Scope | Storage | Applies when |
|---|---|---|
| Global | ~/.config/obey/global-rules.json |
Every project, every session |
| Stack | ~/.config/obey/stack-rules.json |
Project has matching stack file (Cargo.toml, package.json, etc.) |
| Project | .claude/obey.rules.local.json |
Only in this project directory |
Stack detection checks for: Cargo.toml (rust), package.json (node), pyproject.toml/setup.py/requirements.txt (python), go.mod (go), pom.xml/build.gradle (java).
Hook-enforced (actively blocked):
git pushto main/mastergit push --forcecargo publish/npm publish--visibility public(making repos public)rm -rf(dangerous deletions).unwrap()in Rust codeconsole.log()in production code- Editing
.envfiles - Any custom pattern you define
Instruction-enforced (reminded at the right moment):
- Style preferences ("prefer tabs over spaces") → reminded before every Write/Edit
- Process rules ("always explain before coding") → reminded before every Write/Edit
- Quality standards ("keep functions under 50 lines") → reminded before every Write/Edit
- Command rules ("always run tests before committing") → reminded before every Bash command
- General guidance ("keep responses short") → reminded at session start only
Instruction rules are smart about when to remind — a rule about writing code only triggers before Write/Edit, not before every Bash command.
obey hooks into every event in the Claude Code lifecycle — 17 hooks total:
| Hook | Purpose |
|---|---|
| SessionStart | Inject all rules into context at session start |
| InstructionsLoaded | Re-inject rules when CLAUDE.md loads or reloads |
| UserPromptSubmit | Detect natural rule statements, auto-save them |
| PreToolUse | Block violations + inject reminders before tools |
| PermissionRequest | Auto-deny actions that violate rules |
| PostToolUse | Check output for violations + audit trail |
| PostToolUseFailure | Check if failure relates to a rule violation |
| SubagentStart | Inject rules into subagent context |
| SubagentStop | Audit subagent completion |
| Stop | Completion checklist — Claude can't finish until done |
| PreCompact | Rules survive context compaction |
| PostCompact | Fresh injection after compaction |
| TaskCompleted | Per-task completion checklist |
| ConfigChange | Remind about rules when settings change |
| Notification | Remind about active rules when idle |
| SessionEnd | Audit session end |
Rules with stop scope fire when Claude tries to finish:
/remember always run tests before finishing
/remember always update the README before finishing
/remember summarize what you did before stoppingClaude cannot stop until the checklist is complete.
Rules can check tool output after execution:
/remember warn if test output contains failures # checks Bash output for FAIL/ERROR
/remember warn if TODO comments in written code # checks Write output for TODO/FIXMEEvery Bash command, file write, and edit is logged to ~/.config/obey/audit/YYYY-MM-DD.log:
14:30:05 [abc12345] BASH: git push origin main
14:30:12 [abc12345] WRITE: src/main.rs
14:30:15 [abc12345] EDIT: src/lib.rs
14:31:00 [abc12345] SESSION END (clear)
Even without /remember, obey detects rule-like language and saves it automatically:
You: "don't make repos public without asking"
Claude: "I saved this as a rule: 'Don't make repos public without asking'.
Scope: global. Want to keep it or remove it?"
Detected patterns: "never", "always", "don't", "make sure", "prefer", "should", "must", "from now on"
Works on Linux, macOS, and Windows (Git Bash/MSYS2). All scripts use temp files instead of pipes to avoid /proc/fd/ issues on Windows.
/plugin uninstall obey@lexxes-plugins
If the plugin entry persists in settings.json, manually remove the "obey@lexxes-plugins": true line.
Clean up rule files:
rm -rf ~/.config/obey # Global + stack rules
rm -f .claude/obey.rules.local.json # Project rulesDoes this slow Claude down?
Barely. The SessionStart hook runs once per session (~50ms). The PreToolUse hook only fires on Bash/Edit/Write tools and does a fast grep match (~10ms). Instruction-only rules have zero runtime cost — they're just text in the context.
Can I share rules with my team?
Global and stack rules are personal (stored in ~/.config/obey/). Project rules in .claude/obey.rules.local.json are gitignored by default. If you want to share project rules, remove the gitignore entry and commit the file.
What if I want to bypass a rule temporarily?
When a rule blocks an action, Claude will tell you. You can say "yes, do it anyway this time" and Claude can ask you to approve the specific action. The rule stays active for next time.
How is this different from hookify?
hookify requires you to manually write .local.md files with regex patterns. obey lets you say /remember never push to main and handles everything — scope detection, pattern generation, storage, and enforcement. obey also supports global and stack-specific rules, not just project-level.
MIT
Built by Lexxes Projects
If obey saves you from rule-breaking AI, support the project
