{"id":49940910,"url":"https://github.com/jhaizhou-ops/pinrule","last_synced_at":"2026-05-19T19:00:54.988Z","repository":{"id":357967477,"uuid":"1237898891","full_name":"jhaizhou-ops/pinrule","owner":"jhaizhou-ops","description":"Pin the 5-10 rules your AI must not drift from during long tasks — Claude / Codex / Cursor. Pure engineering, zero LLM, ~50-70ms hook latency, ~2% token overhead in typical dogfood.","archived":false,"fork":false,"pushed_at":"2026-05-17T17:03:20.000Z","size":2952,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-17T17:25:52.793Z","etag":null,"topics":["agent-rules","agent-tooling","ai-agent","claude-code","codex-cli","coding-assistant","cursor","developer-tools","hooks","llm","pinrule","prompt-engineering"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pinrule/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jhaizhou-ops.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-13T16:02:52.000Z","updated_at":"2026-05-17T16:58:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jhaizhou-ops/pinrule","commit_stats":null,"previous_names":["jhaizhou-ops/karma","jhaizhou-ops/pinrule"],"tags_count":149,"template":false,"template_full_name":null,"purl":"pkg:github/jhaizhou-ops/pinrule","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhaizhou-ops%2Fpinrule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhaizhou-ops%2Fpinrule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhaizhou-ops%2Fpinrule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhaizhou-ops%2Fpinrule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhaizhou-ops","download_url":"https://codeload.github.com/jhaizhou-ops/pinrule/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhaizhou-ops%2Fpinrule/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33160168,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"ssl_error","status_checked_at":"2026-05-17T22:39:10.741Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-rules","agent-tooling","ai-agent","claude-code","codex-cli","coding-assistant","cursor","developer-tools","hooks","llm","pinrule","prompt-engineering"],"created_at":"2026-05-17T11:02:13.301Z","updated_at":"2026-05-19T19:00:54.982Z","avatar_url":"https://github.com/jhaizhou-ops.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pinrule\n\n**[🇬🇧 English (current)](./README.md) · [🇨🇳 中文](./README.zh.md)**\n\n[![CI](https://github.com/jhaizhou-ops/pinrule/actions/workflows/ci.yml/badge.svg)](https://github.com/jhaizhou-ops/pinrule/actions/workflows/ci.yml)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](https://github.com/jhaizhou-ops/pinrule/actions)\n[![Latest Release](https://img.shields.io/github/v/release/jhaizhou-ops/pinrule?label=release)](https://github.com/jhaizhou-ops/pinrule/releases)\n[![Last Commit](https://img.shields.io/github/last-commit/jhaizhou-ops/pinrule)](https://github.com/jhaizhou-ops/pinrule/commits/main)\n\n**Pin the 5-10 rules your AI must not drift from during long tasks.** Ships with a 7-rule dev preset; switch to any other scenario with one sentence: `/pinrule I mainly do X, switch to this scenario`.\n\n\u003e **Runtime**: pure engineering · zero LLM · zero network · zero runtime deps · ~50-70ms hook · ~2% token overhead. (Scenario rule pack generation runs in your Agent — see Path B below.)\n\n![pinrule demo — 5 scenes, animated SVG](./assets/demo-en.svg)\n\nAndrej Karpathy's [CLAUDE.md](https://github.com/forrestchang/andrej-karpathy-skills) teaches your AI *how* to write good code. pinrule keeps your AI *aligned with your personal preferences* in long tasks — what to never do, what to always do, what to push back on — so you don't have to repeat yourself every 30 turns.\n\n---\n\n## Quick start\n\n### Let your Agent install it (recommended — least friction)\n\nSince you're already using Claude Code / Codex / Cursor (otherwise you wouldn't need pinrule), paste this prompt to your Agent:\n\n```\nInstall pinrule (github.com/jhaizhou-ops/pinrule) — a universal AI behavior rule\nframework that keeps my long-task rules from being lost. Steps:\n\n1. Verify Python is actually installed (Windows: run `python --version` — if it\n   silently exits to Microsoft Store, first `winget install Python.Python.3.12`\n   and reopen PowerShell). Use `python -m pinrule` form on Windows to avoid PATH issues.\n2. pip install pinrule\n3. pinrule init      # auto-installs default rules + hooks for every detected client\n4. pinrule doctor    # verify install\n5. Show me the 7 default rules + how to add my own via /pinrule\n```\n\nThe Agent figures out your OS, Python state, and which clients you have. After install, restart your client and rules take effect.\n\n### Manual install\n\n```bash\npip install pinrule \u0026\u0026 pinrule init\n```\n\n`pinrule init` auto-installs hooks for any detected client (Claude / Codex / Cursor / Hermes) + writes default rules to `~/.pinrule/`. If you install a new client later, run `pinrule install-hooks` to wire it up.\n\nRestart Claude / Codex / Cursor / Hermes — default rules become active once hooks load.\n\n**Uninstall** — `pinrule uninstall-hooks` (auto-removes pinrule entries from every detected client surgically; doesn't touch hooks installed by other tools).\n\n\u003e **Windows without Python**: `python --version` silently jumping to Microsoft Store means no real Python — install via `winget install Python.Python.3.12`, reopen PowerShell, then use `python -m pip install pinrule \u0026\u0026 python -m pinrule init` (the `python -m` form avoids needing `Scripts\\` on PATH).\n\n---\n\n## What pinrule does\n\n- **Injects** your 5-10 directions at session start, compact anchor each turn, full reinject on long-context decay.\n- **Blocks drift in real time** — Bash `sleep`, Edit-before-Read, \"let me hardcode this\" intent declarations all caught before they ship.\n- **Survives compact** — dumps full rule state pre-compact; reloads + re-injects post-restart.\n\nPer-hook lifecycle: see [ARCHITECTURE.md](./docs/ARCHITECTURE.md#backend-capability-matrix).\n\n---\n\n## How it fits together\n\n```mermaid\nflowchart LR\n    R[(rules.json\u003cbr/\u003e5-10 core directions)]\n    K[pinrule engine\u003cbr/\u003eregex + counting]\n    A[🤖 Agent\u003cbr/\u003eClaude / Codex / Cursor / Hermes]\n    V[(violations.jsonl\u003cbr/\u003eaudit history)]\n\n    R ==\u003e K\n    K ==\u003e|prompt header| A\n    A ==\u003e|tool call / response| K\n    K -.-\u003e|hit → deny + log| V\n    V -.-\u003e|next-turn drift marker| K\n```\n\n`rules.json` is the only thing you maintain. The engine reads it, injects at the right hook points, watches Agent traffic for drift — no retrieval, no scoring, no LLM in the loop.\n\n---\n\n## Not just another AI memory tool\n\n| Tool category | What it stores | When it fires |\n|---|---|---|\n| **Memory** (mem0, Claude memory) | Facts about you (preferences, history, profile) | Agent chooses to query |\n| **pinrule** | Behaviors you've articulated as long-term directions | Hooks fire automatically every prompt + every tool call |\n\nUse both. Memory holds \"I prefer TypeScript\"; pinrule enforces \"non-negotiable directions, hook-enforced.\"\n\n---\n\n## Performance\n\n| | |\n|---|---|\n| **Runtime deps** | 0 (Python stdlib only — JSON, no third-party packages) |\n| **Rule count** | 7 default (dev-scenario preset) · soft cap 10 · hard cap 12 (load refused beyond) |\n| **Hook latency** | ~50-70ms typical (machine-bound; reproduce via `scripts/measure_perf.py`) |\n| **Token overhead** | ~2% of conversation context in real dogfood (methodology: [docs/EVALUATION.md](./docs/EVALUATION.md)) |\n| **Tests** | 800+ unit tests, [green on 6-matrix CI](https://github.com/jhaizhou-ops/pinrule/actions/workflows/ci.yml) (ubuntu + macOS + Windows × Python 3.11 / 3.12) |\n| **Supported clients** | Claude / Codex / Cursor / Hermes — [add a backend](./pinrule/backends/HOWTO.md) |\n\n---\n\n## `/pinrule` — one command, three jobs\n\nYou only need to remember one command — `/pinrule`. Based on the natural-language content you type, the pinrule skill auto-dispatches to one of three paths, guides your Agent through tone refinement, schema validation, and monitoring wiring, then writes to your rule library after your confirmation.\n\n| You type | Routes to | Wall time |\n|---|---|---|\n| **`/pinrule`** (no args) | **Data dashboard** — which engine checks fire most, real-vs-false-positive split | \u003c1s (pure CLI, no LLM synthesis) |\n| **`/pinrule \u003csingle rule\u003e`** | **Path A: add / modify / remove one rule** — 7-step skill flow | ~30s |\n| **`/pinrule \u003cscenario, switch to this\u003e`** | **Path B: scenario rule pack** — synthesize 5-7 rules from 4 signals, two-phase confirm, atomic batch write | 3-5 min |\n\nPath A: `/pinrule When I say \"done\" I want test pass evidence attached` → 30s end-to-end.\n\nPath B: see next section.\n\n---\n\n## Switch any work scenario in one line\n\nWhatever your work is, your Agent researches the matching rule pack:\n\n```\n/pinrule I mainly do UX user research + interviews, switch to this scenario\n```\n\nThe Agent synthesizes 4 signals into a 5-7 rule pack:\n\n| Signal | Content |\n|---|---|\n| **A. Your local rule files** | `~/.claude/CLAUDE.md` / `~/.codex/AGENTS.md` / project `CLAUDE.md` / `.cursor/rules/*.mdc` |\n| **B. Online best practices** | `WebSearch` finds high-star GitHub repos / industry blogs / papers |\n| **H. Karpathy CLAUDE.md baseline** | Cross-scenario engineering principles |\n| **S. Session context** | What you're working on right now |\n\nTwo-phase approval (content → mechanism), then atomic batch write with backup. Full walkthrough: [SKILL.md Path B](./skills/pinrule/SKILL.md).\n\n\u003e **Boundary**: pinrule runtime does not call LLMs or the network. Your Agent does the scenario research; pinrule validates and runs the resulting rules locally.\n\n---\n\n## Tried and rejected\n\nSeveral ideas looked attractive but failed in practice. Recorded so the same paths don't get re-walked:\n\n| Tried | Why rejected |\n|---|---|\n| **LLM auto-distilling new rules** | Latency + noise. Hearing something once doesn't make it a long-term direction. |\n| **Retrieval / cosine recall** | The pain is \"persistence,\" not \"recall\" — 5-10 rules can be always-on. |\n| **More than 12 rules** | LLMs pattern-match \"a rule list exists\" instead of reading it ([Mnilax's 30-codebase study](https://x.com/Mnilax/status/2053116311132155938)). |\n| **Reshipping as MCP server** | Hooks are *enforced*; MCP tools are *chosen*. In long-session decay, the Agent drifts before it asks \"what rules apply.\" |\n\n---\n\n## Honest tool boundaries\n\npinrule is **regex + counting**, not LLM semantic understanding. Each known failure mode has a regression test you can run yourself:\n\n| Failure mode | Evidence you can reproduce |\n|---|---|\n| **False positives** (table cells quoting a term, `python -c` literals, commit messages) | `pytest tests/test_check_fp_fixes_v0_16_13.py` — locks down 4 historical FP fixes (negation prefix, fenced code blocks, inline backticks, full-width punctuation). `pinrule audit` flags suspected FPs at runtime. |\n| **False negatives** (Agent disguising a violation) | `pytest tests/test_false_negative_regression.py` — 30+ FN cases pinned. Regex can't read intent — pinrule assumes you're not cheating yourself. |\n| **Zero hits ≠ fix correct** | Pattern may just be too wide. Cross-check with `pinrule audit` on real session data, not synthetic prompts. |\n\nSits between `git` and a linter — signals, not verdicts.\n\n---\n\n## FAQ\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eNothing happens after install?\u003c/b\u003e\u003c/summary\u003e\nRun \u003ccode\u003epinrule doctor\u003c/code\u003e — checks hook events, rule loading, session state.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eToo many false positives?\u003c/b\u003e\u003c/summary\u003e\n\u003ccode\u003epinrule audit\u003c/code\u003e shows triggers tagged \"⚠️ possible false positive\" — report via Issue. Disable a single rule: \u003ccode\u003epinrule rule remove \u0026lt;id\u0026gt;\u003c/code\u003e, or edit \u003ccode\u003e~/.pinrule/rules.json\u003c/code\u003e and remove its \u003ccode\u003eviolation_keywords\u003c/code\u003e / \u003ccode\u003eviolation_checks\u003c/code\u003e fields.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCustom rule sets for non-dev scenarios (writing / research / legal / UX)?\u003c/b\u003e\u003c/summary\u003e\nSay \u003ccode\u003e/pinrule I mainly do X scenario, switch to this\u003c/code\u003e. Agent synthesizes 5-7 rules from 4 signals (your local \u003ccode\u003eCLAUDE.md\u003c/code\u003e / \u003ccode\u003eAGENTS.md\u003c/code\u003e / \u003ccode\u003e.cursor/rules\u003c/code\u003e, online best practices via WebSearch, Karpathy baseline, session context), previews with source attribution, two-phase confirms, atomic batch write — 3-5 min end-to-end. See \u003ca href=\"#switch-any-work-scenario-in-one-line\"\u003e\"Switch any work scenario\"\u003c/a\u003e above.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eHow do I sync rules across devices?\u003c/b\u003e\u003c/summary\u003e\nAsk the Agent to copy \u003ccode\u003e~/.pinrule/rules.json\u003c/code\u003e. \u003cb\u003eSafe to sync\u003c/b\u003e: \u003ccode\u003erules.json\u003c/code\u003e + \u003ccode\u003econfig.json\u003c/code\u003e. \u003cb\u003eNever sync\u003c/b\u003e: \u003ccode\u003eviolations.jsonl\u003c/code\u003e, \u003ccode\u003esession-state/\u003c/code\u003e (runtime data, per-device — cloud-synced folders can corrupt cross-device state).\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDoes this overlap with Karpathy's CLAUDE.md?\u003c/b\u003e\u003c/summary\u003e\nComplementary. Karpathy's 12 rules are \u003cb\u003euniversal coding principles\u003c/b\u003e (cross-user). pinrule's are \u003cb\u003epersonal preferences\u003c/b\u003e (per-user). Use both.\n\u003c/details\u003e\n\n---\n\n## What Agents say after running pinrule\n\n\u003e **Claude (Opus 4.7)**: Like having a senior tech director reviewing every action in real time — tiring, but it delivers. Without pinrule, a lot more behavior-the-user-didn't-want would have shipped.\n\u003e\n\u003e **Codex (GPT 5.5)**: I noticed myself being \"behaviorally nudged,\" but didn't strongly feel \"blocked or interrupted.\"\n\u003e\n\u003e *— Matches pinrule's positioning: guardrails + background noise, speaking up only when you hit a rule.*\n\n---\n\n## Mental model\n\n\u003e A rules file isn't a wishlist. It's a behavioral contract closing out failure modes you've actually observed. Each rule should answer: **what error is this rule preventing?**\n\nThe 7 default rules in `data/rules.dev.example.json` are pain points from self-use, not a template to copy verbatim. Keep what matches your own failure scenes, replace the rest via `/pinrule \u003cnatural language\u003e`.\n\n---\n\n## Documentation\n\n- [PRD.md](./docs/PRD.md) — product requirements + scenario positioning\n- [ARCHITECTURE.md](./docs/ARCHITECTURE.md) — hook protocol, 8 check implementations, sandbox model\n- [HOOK_CONFIGURATION_GUIDE.md](./docs/HOOK_CONFIGURATION_GUIDE.md) — per-hook lifecycle + tunable thresholds\n- [EVALUATION.md](./docs/EVALUATION.md) — methodology behind performance numbers (hook latency, token overhead)\n- [CHANGELOG.md](./CHANGELOG.md) — release notes (grouped by minor version)\n- [CODEX_BACKEND.md](./docs/CODEX_BACKEND.md) — Codex backend ownership boundary\n- [CLAUDE.md](./CLAUDE.md) — project charter for Claude collaboration\n\nAll bilingual (`.md` English + `.zh.md` Chinese).\n\n## Acknowledgments\n\n- [Andrej Karpathy's CLAUDE.md template](https://github.com/forrestchang/andrej-karpathy-skills) — universal coding-principles companion to pinrule's personal preferences.\n- [Mnilax's 30-codebase 6-week CLAUDE.md study](https://x.com/Mnilax/status/2053116311132155938) — pinrule's soft cap 10 / hard cap 12 comes from this.\n\n## Contributing\n\n- Bugs / ideas: [GitHub Issues](https://github.com/jhaizhou-ops/pinrule/issues)\n- Add a new AI client backend: [HOWTO](./pinrule/backends/HOWTO.md)\n- Scenario rule templates: PR to `data/`\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhaizhou-ops%2Fpinrule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhaizhou-ops%2Fpinrule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhaizhou-ops%2Fpinrule/lists"}