https://github.com/Lexxes-Projects/obey
Makes Claude actually follow your rules. Save rules with natural language, enforce them with hooks, remember them across sessions.
https://github.com/Lexxes-Projects/obey
ai claude claude-code developer-tools hooks plugin productivity rules
Last synced: 2 months ago
JSON representation
Makes Claude actually follow your rules. Save rules with natural language, enforce them with hooks, remember them across sessions.
- Host: GitHub
- URL: https://github.com/Lexxes-Projects/obey
- Owner: Lexxes-Projects
- License: mit
- Created: 2026-03-22T11:11:46.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-22T13:38:46.000Z (3 months ago)
- Last Synced: 2026-04-04T14:01:37.112Z (3 months ago)
- Topics: ai, claude, claude-code, developer-tools, hooks, plugin, productivity, rules
- Language: Shell
- Size: 295 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-claude-code-toolkit - obey - specific, project-local), active blocking via PreToolUse, completion checklists via Stop hook, audit trail, auto-detects rule-like language. Cross-platform. | (Plugins / All Plugins)
README
obey
Makes Claude actually follow your rules.
---
## The problem
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.
## The solution
**obey** is a Claude Code plugin that stores your rules, injects them into every session, and actively blocks violations.
```bash
/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.
## How it works
```
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
```
## Install
### From marketplace
```
/plugin marketplace add https://github.com/Lexxes-Projects/lexxes-plugins.git
/plugin install obey@lexxes-plugins
```
### Local development
```
claude --plugin-dir /path/to/obey
```
### Requirements
- `jq` — auto-installed on first run (via apt, brew, choco, pacman, or dnf)
## Commands
### `/remember [flags]`
Save a persistent rule.
```bash
/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 only
```
**Flags:**
- `--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
### `/rules [flags]`
Show all active rules.
```bash
/rules # Show all rules
/rules --global # Global rules only
/rules --local # Project rules only
/rules --stack # Stack-specific rules only
```
### `/forget `
Remove a rule.
```bash
/forget 17741838840474 # Remove by ID (shown in /rules output)
/forget force push # Remove by keyword search
```
## Rule scopes
| 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).
## What gets enforced
**Hook-enforced (actively blocked):**
- `git push` to main/master
- `git push --force`
- `cargo publish` / `npm publish`
- `--visibility public` (making repos public)
- `rm -rf` (dangerous deletions)
- `.unwrap()` in Rust code
- `console.log()` in production code
- Editing `.env` files
- 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.
## Full hook coverage
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 |
### Completion checklist (Stop hook)
Rules with `stop` scope fire when Claude tries to finish:
```bash
/remember always run tests before finishing
/remember always update the README before finishing
/remember summarize what you did before stopping
```
Claude cannot stop until the checklist is complete.
### Post-tool checks
Rules can check tool output after execution:
```bash
/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/FIXME
```
### Audit trail
Every 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)
```
## Natural rule detection
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"
## Cross-platform
Works on **Linux**, **macOS**, and **Windows** (Git Bash/MSYS2). All scripts use temp files instead of pipes to avoid `/proc/fd/` issues on Windows.
## Uninstall
```
/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:
```bash
rm -rf ~/.config/obey # Global + stack rules
rm -f .claude/obey.rules.local.json # Project rules
```
## FAQ
Does 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.
## License
MIT
---
Built by Lexxes Projects
If obey saves you from rule-breaking AI, support the project