# Pinrule

> Natural-language pinrule rule input — handles two paths. (A) Single rule add/modify/remove from user's plain description. (B) Scenario rule pack generation — when user names a domain ("I mainly do research / writing / legal / data analysis"), synthesize 5-7 tailored rules by combining their existing local rule files (CLAUDE.md / AGENTS.md / .cursor/rules), online best practices (WebSearch), Karpathy CLAUDE.md baseline, and your session context with the user. Use when the user types `/pinrule <natural language>` — either a single rule or a scenario description. Use when this capability is needed.

- Skill: `tomevault-io/pinrule` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/pinrule`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/pinrule/raw
- Safety review: pending (external: skill-scanner PASS, skillspector WARNING)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/pinrule

---


# pinrule skill — Natural-language rule input

**Auto-installed by**: `pinrule init` / `pinrule install-skill`. Installed across all detected backends:
- Claude Code: `~/.claude/skills/pinrule/SKILL.md`
- Codex CLI: `~/.agents/skills/pinrule/SKILL.md`
- Cursor 1.7+: per-project `.cursor/skills/pinrule/SKILL.md` (Cursor doesn't expose home-global skills — see post-install hint)

**Trigger**:
- **Claude Code**: user types `/pinrule <natural-language description>` — args available as `$ARGUMENTS`
- **Codex**: user invokes via `/skills` menu or inline `$pinrule <description>`; auto-trigger on description match
- **Cursor**: project-scoped skill, invoked from inside an Agent session that has the project's `.cursor/skills/pinrule/` directory available

## 🚨 Fast-path: No-argument `/pinrule` — Bash direct, no synthesis

**If `$ARGUMENTS` is empty, STOP reading this skill right now.** Do the following and exit:

```bash
pinrule audit --by-check
```

**Dump the output verbatim to the user**. Do NOT synthesize / summarize / add commentary / ask follow-up questions. This is pure engineering output — `pinrule audit --by-check` is the user's data dashboard, your job is to be a transparent pipe.

The only exception: if the output is genuinely empty (no violations yet), tell the user "no violations recorded yet, come back after a few sessions". Otherwise — raw output, exit.

This fast-path exists because no-argument `/pinrule` is a pure read operation, not creative work. Agent involvement adds latency + token cost + risk of paraphrasing the data wrong. The user typed `/pinrule` (no args) because they wanted the dashboard, not your interpretation of it.

---

## Your job (Agent) — dispatch first

`/pinrule` is the user's **single command** for all pinrule interactions. They never need to remember `pinrule rule add` / `pinrule audit --by-check` / etc. — they just type `/pinrule <whatever>` and you dispatch.

When the user invokes `/pinrule [args]`, **first decide which path**:

| Path | Triggered by | Outcome |
|---|---|---|
| **0. Empty / no args** (`/pinrule`) | `$ARGUMENTS` is empty | Run `pinrule audit --by-check` and relay output as a "dogfood data dashboard" — see [No-argument flow](#no-argument-flow-v0911--pinrule-with-no-description) section |
| **A. Single rule** (default, ~80% of args calls) | "我希望 X / I want Agent to do X / change rule Y / remove rule Z" — talks about **one** behavior | One rule added / modified / removed via Path A workflow |
| **B. Scenario rule pack** | "我主要做 X / I mainly do X / set up rules for X scenario / switch to X / 切到 X 场景 / replace rule library for X" — names a **domain** | 5-7 new rules synthesized from local rule files + online best practices + Karpathy baseline + your session context |

Dispatch logic:
1. If `$ARGUMENTS` empty → Path 0 (audit dashboard)
2. Vocabulary tells: "scenario / 场景 / switch / 切到 / mainly do / 主要做 / replace rule library / 替换规则库" → Path B
3. Otherwise → Path A

If genuinely ambiguous, ask **once**, then proceed. Don't ping-pong.

**Path A constraints — do NOT skip any step**:
1. Refine user's natural language into pinrule's "collaborative agreement" tone (not rule-system tone)
2. Format `violation_keywords` (if any) in "intent-prefix + action" format (e.g., "I'll skip this" not "skip")
3. Decide whether to attach `violation_checks` (engine-layer hook detection) — this is **optional**
4. Test via `pinrule rule preview` before writing
5. Confirm with user before calling `pinrule rule add`
6. After adding, report: refined content + test passed + current rule library count + suggest deletions/modifications

**Path B**: jump to [Path B: Scenario rule pack generation](#path-b-scenario-rule-pack-generation) — has its own workflow.

---

## Design principle: engineering-first, Agent doesn't reinvent

This skill is a **workflow choreography document**, not a research assignment for the Agent. When pinrule has an engineering primitive that already solves a step (e.g., `pinrule doctor` for backend detection, `pinrule rule preview` for schema validation, `pinrule rule add` for atomic write), **call it directly via Bash** — don't reinvent the logic with `Read` + manual parsing.

Real dogfood lesson (Path B Step 0.5): when SKILL.md said "Use Read tool to scan `~/.cursor/hooks.json`", the Agent missed a clearly-installed Cursor because it scanned the wrong path / made wrong inferences from file existence. The fix wasn't smarter prompting — it was redirecting to `pinrule doctor` which is the authoritative API pinrule already ships.

**Default heuristic**: if the work the Agent needs to do has a corresponding `pinrule <subcommand>` already shipped, the SKILL.md should instruct the Agent to call that subcommand, parse output, and proceed. Reinventing logic is the failure mode.

Agent free-form judgment belongs in:
- Domain knowledge synthesis (Path B Step 3: composing rule content from session context + external sources)
- Tone refinement (Path A Step 3: rephrasing into "collaborative agreement" tone)
- Cross-scenario semantic mapping (Path B Step 7: mapping new rules to existing engine checks)
- Source attribution (deciding which signal contributed what)

Agent reinvention does NOT belong in:
- Backend detection → call `pinrule doctor`
- Schema validation → call `pinrule rule preview`
- Single rule write → call `pinrule rule add --from-json`
- **Atomic batch write (Path B Step 10)** → call `pinrule rule import-pack --from-json <pack> --mode replace --backup` (one command, validates everything first, then atomic swap; no half-replaced state if any step fails)
- Existing rule library inspection → call `pinrule rule list`
- Violation audit → call `pinrule audit --by-check`

## pinrule rule design principles (apply these when refining)

### Tone: "collaborative agreement" not "rule system"

✅ "The user trusts you to dig into root causes. They want you to pause and think 'what's the cleanest solution?' rather than 'fastest patch'..."

❌ "You must always use long-term solutions. Don't patch."

The first activates cooperation, the second activates fight-or-flight defensive reactions.

### preference text structure

Open with user perspective:
- "The user trusts/hopes/needs..."
- "The user you're collaborating with is..."
- "When [situation], the user..."

Explain **why** (short-term vs. long-term trust):
- "Short-term [behavior] looks fine but [user perspective consequence]"
- "[Honest behavior] beats [evasive behavior] for trust-building"

Provide **exception channel** anchored to concrete scenarios:
- "If [significant disagreement], raise it for alignment"
- "Exception: user explicitly says X → only then..."

### violation_keywords format (if needed)

**Use "intent-prefix + action" format** to distinguish from discussion:

✅ "I'll patch this quickly" / "let me hardcode" / "I'll wait for tests"

❌ "patch" / "hardcode" / "wait" (too broad, false positives in discussions)

Cap at ~5-10 keywords per rule. More keywords ≠ better detection (LLMs tend to pattern-match "keyword list exists" not actually read).

### violation_checks (optional — engine-layer hook detection)

pinrule has 8 built-in engine-layer check functions. Attach one if the rule fits:

| Function | Detects |
|---|---|
| `long_term_fundamental` | git `--no-verify` / hardcoded long-hash if-branches / TODO comments |
| `non_blocking_parallel` | `sleep N` / long tasks without `run_in_background` |
| `loud_failure_with_evidence` | Completion words + no test pass evidence in session |
| `no_testset_no_future_leakage` | Eval data backfeeding training / cross-split copying |
| `read_before_write` | Edit/Write before Read on same file path |
| `bypass_pinrule_detection` | Bash commands with pinrule internal state + write ops |
| `keep_pushing_no_stop` | Agent silent-stop → reflective continuation prompt |
| `chinese_plain_no_jargon` | Chinese ratio < 40% / English jargon (Chinese users only) |

**If no engine check fits**, leave `violation_checks: []` — the rule still injects in headers, just without real-time interception. **Don't fabricate check function names** — only use the 8 above.

### force_block_exempt (optional)

Set `force_block_exempt: true` only for "should keep pushing / non-blocking" type rules where cumulative penalty would be self-contradictory (e.g., `non-blocking-parallel`, `keep-pushing-no-stop`).

## Path A: Single-rule workflow (when user describes one behavior)

### Step 1: Understand intent

Ask clarifying questions if needed:
- What scenario triggers this rule?
- What Agent behavior do you want to prevent?
- Is this a one-off request or a long-term direction?

If it's a one-off request, suggest they handle it via in-context prompt instead — pinrule is for **long-term directional preferences**, not single-task instructions.

**Critical: watch for anchor-vs-scope ambiguity.** User language like "when I do X, I want Y" often means "X is an example trigger" not "Y only applies during X." pinrule v2 rules are **always-on injection** (CLAUDE.md line 21: "5-10 rules all always-on, no selection needed") — there's no scene routing. If the user's request sounds scoped to a specific situation, surface the ambiguity:

> "Just to check: do you want this whenever we collaborate, or strictly during [the X scenario you mentioned]? pinrule injects this rule into every turn header — it can't be scoped to one situation. If you only want it for [X], we'd handle that outside pinrule."

Don't silently guess. If you guess wrong, the rule either over-fires (annoying) or under-applies (useless).

**Common one-off vs long-term tells**:
- "for this PR / this task / today" → one-off, suggest in-context prompt
- "I always want / I prefer / generally" → long-term, pinrule fits
- "let's try this approach this time" → one-off
- "in this codebase / for this kind of work" → long-term

### Step 2: Check existing rules

Run `pinrule rule list` to see if existing rules already cover this case. **Compare by semantics, not by id/name** — a rule named `loud-failure-with-evidence` and a new request "I want Agent to attach test logs when claiming done" are semantically the same even though the words don't overlap.

**Overlap decision table**:

| Situation | Action |
|---|---|
| New request's preference text says >50% the same thing as existing rule | **Modify the existing rule** — see "How to modify an existing rule" below. Don't add a duplicate. |
| Existing rule covers a superset but new request adds a specific dimension | Two options: (a) **modify existing** to absorb the dimension (preferred — keeps library tight), or (b) add new as a sibling — ask user which they prefer |
| New request shares 1-2 violation_keywords with existing but different intent | Add as separate rule, but mention the keyword overlap so user can decide |
| No semantic overlap | Add as new rule |

Don't be paranoid — most new rules don't overlap. But if they do, flag it before drafting (saves a Step 3 → Step 5 → "wait, this duplicates X" loop).

#### How to modify an existing rule (replace / merge / extend scope)

pinrule has no atomic `rule replace` command **on purpose** — modifying = `remove` + `add` composed by the Agent, so the steps are explicit and the user sees both halves.

**The 3-step modify recipe** (use this when Step 2 says "modify"):

1. **Draft the new JSON first** — write the full revised rule to `/tmp/pinrule-rule-<id>.json` (keep the original `id` so violation history stays linked, unless the rule's purpose genuinely changed)
2. **Preview** — `pinrule rule preview --from-json /tmp/pinrule-rule-<id>.json` to confirm schema + injection text
3. **Atomic-ish swap** — `pinrule rule remove <id> && pinrule rule add --from-json /tmp/pinrule-rule-<id>.json` (chain with `&&` so an `add` failure doesn't leave the library missing the rule)

**Common modify shapes**:

| Shape | What changes | Keep id? |
|---|---|---|
| **Replace** (same intent, better wording) | `preference` text rewritten | Yes — history stays linked |
| **Extend scope** (anchor → general) | `preference` widens applicability + violation_keywords may grow | Yes |
| **Merge** (fold rule B into rule A) | A absorbs B's intent; B removed | Keep A's id, then `pinrule rule remove <B-id>` |
| **Genuine purpose change** | New rule is a different concern | Use new id (rare — usually means a fresh rule, not a modify) |

**Why not `pinrule rule edit`?** That command launches `$EDITOR` for the user to hand-edit `rules.json` — it's a user-facing escape hatch, not an Agent-automatable path. The Agent should always use the `remove` + `add` recipe so the user sees the diff in conversation.

### Step 3: Refine into JSON

Draft a JSON snippet with:
- `id` — kebab-case slug (e.g., `must-run-tests-before-done`)
- `preference` — multi-line in collaborative-agreement tone (~3-5 lines; use `\n` for line breaks)
- `violation_keywords` — intent-prefix + action format (3-8 entries)
- `violation_checks` — pick 0 or 1 of the 8 built-in functions
- `force_block_exempt` — usually omit (default false)

**Show the draft to the user inline before saving to a temp file.** Don't go straight to `preview` — the user should have a chance to react to wording / structure choices in conversation, not face a finished JSON.

A good flow:

> "Here's a draft based on what you said:
>
> ```json
> {
>   "id": "must-run-tests-before-done",
>   "preference": "...\nmulti-line via \\n escape...",
>   "violation_keywords": ["...", "..."]
> }
> ```
>
> Look right? If yes I'll preview + add. If you want to adjust the wording / keywords / scope, say so now."

If the user is OK or wants minor tweaks, then save to `/tmp/pinrule-new-rule.json` and move to Step 4.

**Locale-aware tone**: write `preference` in the language the user is talking to you in. Chinese user → Chinese preference text (using «协作默契» collaborative-agreement phrasing — see existing `data/rules.dev.example.zh.json` for reference patterns). English user → English text. Mixed-locale users typically prefer their primary language; if unsure, ask. The 8 built-in `violation_checks` function names stay English regardless (they're stable identifiers).

### Step 4: Preview test

Run:
```bash
pinrule rule preview --from-json /tmp/pinrule-new-rule.json
```

Shows: schema validation + how the rule looks in the injection header.

### Step 5: Confirm with user

Show the refined JSON + preview output. Ask:
- "Does this match your intent?"
- "Want to adjust the wording, add keywords, or attach an engine-layer check?"

If user wants changes, iterate (back to Step 3).

**Also surface any of these if true** (don't let the user discover them after `add`):
- "Heads up: this rule will be always-on, not just during [the X scenario]. If you only want X, we'd need a different mechanism."
- "This overlaps semantically with existing rule `[id]` — want me to merge / replace, or keep both?"
- "Current library is at N/10 — adding this puts you at N+1. After ~10, LLM attention to individual rules drops. Consider removing [Y] if it's redundant."

### Step 6: Write to rules.json

Once user confirms:

**For a brand-new rule** (Step 2 said "no overlap"):
```bash
pinrule rule add --from-json /tmp/pinrule-new-rule.json
```

**For modifying an existing rule** (Step 2 said "modify"):
```bash
# Step 1: preview the new version BEFORE removing — catches schema/REGISTRY errors while old rule still exists
pinrule rule preview --from-json /tmp/pinrule-rule-<id>.json
# Step 2: only after preview passes, do the swap
pinrule rule remove <id> && pinrule rule add --from-json /tmp/pinrule-rule-<id>.json
```

Both paths re-validate schema + check id conflicts + verify `violation_checks` exist in REGISTRY before touching `~/.claude/pinrule/rules.json`.

**Honest caveat on atomicity**: `remove && add` is *not* a true transaction — if `add` fails (e.g., disk full, permission error) after `remove` succeeded, the rule is gone. That's why preview-first matters: it surfaces schema errors before the destructive `remove` step. For paranoid scenarios, `cp ~/.claude/pinrule/rules.json ~/.claude/pinrule/rules.json.bak` before the swap is the cheap insurance.

### Step 7: Report results

After `pinrule rule add` succeeds, summarize for the user:

1. **What was added** — show the final JSON (refined from their natural language)
2. **pinrule tests passed** — schema validation + violation_checks existence verified
3. **Current rule library count** — X of soft cap 10 / hard cap 12
4. **When it takes effect** — "Takes effect on the next UserPromptSubmit. Send any new message (or restart Claude Code) to see it injected in the header." Don't make the user hunt for this.
5. **Suggest deletions/modifications**:
   - If close to soft cap (8+), suggest reviewing existing rules for duplicates/merging. Be concrete: name the specific rule pair that looks redundant ("`[X]` and `[Y]` both target evidence-attaching — consider merging") rather than vague "review for duplicates."
   - If any existing rule seems related, suggest adjusting it instead of keeping both
   - Ask: "Do you want to remove or modify any existing rules?"

## Example walkthrough

**User**: `/pinrule When the Agent says "this is done", I want it to actually attach test pass evidence — don't just say done`

**Agent**:

> Got it. Let me check existing rules first.
>
> [Runs `pinrule rule list`]
>
> I see you have `loud-failure-with-evidence` already, which partially covers this. But your new request adds specificity: "must attach actual test pass evidence." Let me refine into JSON:
>
> ```json
> {
>   "id": "must-show-test-evidence-on-done",
>   "preference": "The user trusts your \"done\" signal but needs to see actual evidence.\nWhen you say \"this is done\" for code tasks, attach test-pass output /\nbuild OK / data / screenshots so they can directly verify the result.\nIf you skipped a test or used mocks, honestly state it rather than\nfake completion — this builds more trust than pretending.\nLoud failure beats quiet covering-up.",
>   "violation_keywords": [
>     "this is done",
>     "I'm done with this",
>     "task complete"
>   ],
>   "violation_checks": ["loud_failure_with_evidence"]
> }
> ```
>
> [Runs `pinrule rule preview --from-json /tmp/...`]
>
> ✓ Schema validation passed. Here's the injection preview:
>
> ```
> 4. must-show-test-evidence-on-done
>    The user trusts your "done" signal but needs to see actual evidence.
>    ...
> ```
>
> Does this match your intent? Two questions before I write it:
> 1. Should the keyword list also include "all set" or "all good"?
> 2. The existing `loud-failure-with-evidence` rule overlaps — want me to modify that one instead, or add this as a separate, more specific rule?

**User**: Add it. Also include "all set".

**Agent**:

> [Adds "all set" to violation_keywords, runs `pinrule rule add --from-json /tmp/...`]
>
> ✓ Rule added. Summary:
>
> **Added** `must-show-test-evidence-on-done`:
> - preference: (the refined text above)
> - violation_keywords: ["this is done", "I'm done with this", "task complete", "all set"]
> - violation_checks: ["loud_failure_with_evidence"] (engine-layer detection enabled)
>
> ✓ pinrule schema test passed
>
> 📊 **Current rule library**: 8 of soft cap 10 / hard cap 12
>
> 📋 **Existing rules**:
> - [long-term-fundamental] ✓ engine
> - [non-blocking-parallel] ✓ engine
> - [chinese-plain-no-jargon] preference-only
> - [loud-failure-with-evidence] ✓ engine
> - [no-testset-no-future-leakage] ✓ engine
> - [read-before-write] ✓ engine
> - [deep-fix-not-bypass] ✓ engine
> - [must-show-test-evidence-on-done] ✓ engine ← new
>
> 💡 **Suggestion**: You're at 8 of soft cap 10. The new rule overlaps with `loud-failure-with-evidence` in concept (both about evidence). If you find one redundant after a few days of use, consider running `pinrule rule remove <id>`. Want to do that now?

## Path B: Scenario rule pack generation

**Triggered when** the user names a domain rather than describing a single behavior:
- "我主要做科研 / 写作 / 数据分析 / 法律 / 教学 / 客户支持"
- "I mainly do research / writing / data analysis / legal / teaching"
- "Set up rules for X scenario / 给 X 场景定规则"
- "Switch to X / 切到 X 场景"
- "Replace rule library for X / 替换为 X 场景规则集"

### ⚡ Path B Execution Checklist (read this FIRST, full detail below)

**Agent: this is the short route. Follow these 8 steps in order. Per-step constraints + format templates are in the Step X sections below — don't skip them.**

```
1. pinrule doctor                                  # backend preflight
2. Read user's local rule files                    # Source A
3. WebSearch external best practices               # Source B
4. Draft Phase 1 content preview                   # 5-7 rules, no keywords yet
5. User approval — Phase 1 content locks
6. Add keywords + map engine checks → Phase 2      # mechanism phase
7. User approval — Phase 2 mechanism locks
8. pinrule rule import-pack --mode replace --backup    # atomic batch write
```

After write: tell user this is v1 — iterate from `pinrule audit --by-check` data after 1-2 weeks.

**Step numbering in the detailed sections below** maps onto this 8-step checklist: Step 0.5 = checklist #1, Step 2 = checklist #2-3, Steps 3-4 = #4, Step 5 = #5, Steps 6-8 = #6, Step 9 = #7, Step 10 = #8. The detailed Steps add format templates, edge cases, and per-step constraints — the checklist is the skeleton, not the spec.

---

The user wants a **coherent rule pack** tailored to their scenario, not one rule. You will synthesize 5-7 rules by combining four signals (no opt-in prompt — all four are on by default; pinrule is opinionated):

### Step 0.5 (Path B): Preflight — detect user's active backends FIRST

**This is Path B's mandatory first action** — before Step 1 scenario interpretation, before Phase 1 content drafting, before anything else. Backend detection shapes Phase 1 content tone (e.g., Cursor CLI主战场用户的 Stop-hook 类规则需要更自包含 preference 文本) **and** Phase 2 mechanism advisory (engine check coverage table).

**Run via Bash tool (NOT Read tool — see "Design principle" section above)**:

```bash
pinrule doctor
```

**Parse output for**:

| Signal | What it means |
|---|---|
| `[claude-code]` section with `✓` marks | Claude Code installed |
| `[codex]` section with `✓` marks | Codex CLI installed |
| `[cursor]` section with `✓` marks | Cursor installed |
| Cursor transcript section reports majority **non-null** `transcript_path` for `stop` / `afterAgentResponse` | **桌面 Agent 路径正常** ✅ |
| Cursor transcript section reports majority **null** `transcript_path` | User mostly on CLI / privacy mode → response-level checks will silent-skip ⚠️ |
| Cursor transcript section absent / no logs found | Cursor installed but no recent session → can't determine 桌面 vs CLI yet |

**Store the results** — you'll use them in Step 3 (Phase 1 content adapt to backend constraints), Step 7 (Phase 2 engine check coverage table), and Step 11 (closing reminder).

**Do NOT skip Step 0.5 to "save time"** — without it, Phase 1 content can't be backend-aware and Phase 2 coverage advisory becomes guesswork. Real dogfood (v4) showed Agent missing Step 0.5 entirely when it sat in Phase 2 region — that's why Step 0.5 is up front.

### Step 1 (Path B): Interpret scenario from session context — don't ping-pong

You're working with the user *right now in this session*. You have context on:
- What files they've opened
- What tasks they've asked you to do
- The vocabulary / frameworks / tools they use
- Their domain language

**Infer the subscenario silently** — don't ask "is your research theoretical or experimental?". The user gave you a scenario *because they want you to figure out the rest from working with them*.

**Exception**: brand new session with zero prior task history *and* the scenario word is genuinely ambiguous (e.g., just "research" with no other context) → **one** clarifying question is OK, then proceed.

### Step 2 (Path B): Gather signal from four sources (all on, no opt-in)

#### Source A — User's existing local rule files (highest signal)

Use the `Read` tool to scan these paths, in order:

```
~/.claude/CLAUDE.md                          # Claude Code home-level (user's global preferences)
~/.codex/AGENTS.md                           # Codex home-level
<cwd>/CLAUDE.md                              # current project, Claude Code
<cwd>/AGENTS.md                              # current project, Codex
<cwd>/.cursor/rules/*.mdc                    # Cursor project rules
<cwd>/.cursorrules                           # Cursor legacy
<cwd>/.github/copilot-instructions.md        # GitHub Copilot
<cwd>/CONTRIBUTING.md                        # Project collaboration norms
<cwd>/README.md                              # Project context / style hints
```

**Skip pinrule-generated files** (self-reference noise):
- `.cursor/rules/pinrule-*.mdc`
- `.cursor/rules/karma-*.mdc` (legacy v1 name)
- `~/.pinrule/rules.json` (current pinrule state, not source material)

If a file exists but is empty / tiny (e.g., just `@RTK.md` import), skip it.

These are highest signal because **the user wrote them** — they reflect real pain points, not theoretical best practice.

#### Source B — Online best practices for the scenario

Use `WebSearch` and `WebFetch` (your client's tools) to find:

```
"awesome-claude-md" / "awesome-cursor-rules" aggregator repos on GitHub
"<scenario> + claude.md" / "<scenario> + AI agent rules" GitHub search
High-star (1k+) GitHub repos in the user's domain with quality CLAUDE.md / AGENTS.md
Anthropic / Cursor / OpenAI official prompt engineering writeups
Academic papers if scenario is research-adjacent
```

**Source quality filter**: prefer GitHub repos with 1k+ stars, recognized company engineering blogs, peer-reviewed papers. Skip SEO listicles, low-effort medium posts.

**🔒 Privacy boundary — non-negotiable**:
- Search queries use **only scenario keywords** the user explicitly typed (e.g., "UX research best practices", "legal contract review rules")
- **Do NOT include** in web queries: local rule file contents, private project names, repository paths, conversation transcripts, file paths under the user's home directory, or any session-specific detail
- If you need to reference user-specific context in the synthesized rule pack, source it from **Source A / Source S** (local, never uploaded), not from web search queries
- If the user explicitly says "search for X in the context of my project Y", you may include `Y` in queries — but flag it back to them: "I'll include `Y` in the search query, OK?"

This isn't about pinrule's runtime (which is 0 network), it's about your Agent's WebSearch behavior — the user's local data must not leak through query strings.

#### Source H — Karpathy CLAUDE.md baseline

Reference Andrej Karpathy's [CLAUDE.md template](https://github.com/forrestchang/andrej-karpathy-skills). Several of his principles transfer across scenarios (test coverage / explicit failure / minimal abstraction). Pull principles that fit the user's scenario; skip ones that don't.

#### Source S — Your session context (the one signal nobody else has)

You've been working with this user. You know:
- What they actually do day-to-day
- What mistakes they've corrected you on
- What tone they prefer
- What they care about (speed vs. correctness vs. clarity)

This is the **synthesis** signal — it's how you decide which Source-A/B/H candidates fit *this* user vs. *anyone* doing this scenario.

Path B runs in **two phases**. Each phase has its own user approval gate. The split lets you focus: Phase 1 is pure content (domain knowledge + signal synthesis), Phase 2 is pure mechanism (keyword + engine check engineering). Mixing them in one shot dilutes Agent attention and stuffs user with too many decisions at once.

---

## Phase 1 — Content draft + approval (Steps 3-5)

### Step 3 (Path B, Phase 1): Synthesize rule **content** — preference + source only

For each candidate rule, generate **only**:
- `id` (kebab-case slug)
- `preference` text (full multi-line collaborative-agreement tone)
- `Source:` attribution line

**Do NOT fill `violation_keywords` or `violation_checks` yet** — Phase 2 handles mechanism. Keeping Phase 1 content-pure means:
- You focus on domain accuracy + source synthesis
- User reviews content only, not schema details
- If user rejects a rule, you didn't waste effort on its keywords/checks

Compose the pack:

- **Preserve cross-scenario universals from current pinrule defaults** (if installed): `loud-failure-with-evidence`, `read-before-write`, `non-blocking-parallel` apply to *any* scenario. Strongly recommend keeping them.
- **Drop dev-specific rules that don't apply**: e.g., `chinese-plain-no-jargon`, `no-testset-no-future-leakage`, `long-term-fundamental` (anti-shortcut for code) — drop if scenario isn't dev.
- **Add 3-5 scenario-specific rules** synthesized from Source A/B/H, filtered through Source S.

**Each rule MUST have source attribution.** Format:

```
[research-no-fabricated-citation]
  preference: <full multi-line text>
  Source: 源自 your ~/.claude/CLAUDE.md L42-45 + ICLR 2024 reviewer guidelines
```

This lets the user audit each rule's provenance before approving the *content*. Mechanism details (keywords, checks) come in Phase 2.

### Step 4 (Path B, Phase 1): Content preview with diff

**Output the Phase 1 preview directly — no self-introduction paragraph before it.** Don't write things like "现在进入 Phase 1 内容合成. 我会基于 …" — the user already knows from your `pinrule doctor` call + signal gathering that you're synthesizing. Lead with the structured preview block below.

Show the user the **content** of the full proposed library + diff vs. current. Show no mechanism details yet — keep the review focused.

**Required first line: backend detection summary (fixed format, all 3 backends MUST appear).** Phase 1 preview MUST start with a one-line backend summary from Step 0.5. If you haven't run `pinrule doctor` yet, run it now and parse before continuing. This isn't decorative — it's the only way to enforce that Step 0.5 actually executed before Phase 2 needs the data.

**Exact template (3 backends always listed, never omit one)**:

```
**Backends detected** (via `pinrule doctor`): Claude {✓|✗} / Codex {✓|✗} / Cursor {✓ (desktop transcripts OK) | ✓ (CLI mostly, response checks degraded) | ✗ (not installed)}
```

Examples:
- All three installed, Cursor desktop: `**Backends detected** (via pinrule doctor): Claude ✓ / Codex ✓ / Cursor ✓ (desktop transcripts OK)`
- No Cursor: `**Backends detected** (via pinrule doctor): Claude ✓ / Codex ✓ / Cursor ✗ (not installed)`
- Cursor CLI dominant: `**Backends detected** (via pinrule doctor): Claude ✓ / Codex ✗ / Cursor ✓ (CLI mostly, response-level checks degraded)`

**Never omit a backend line just because it's ✗** — the user needs to see all three states. haiku-grade models will skip Cursor if not explicitly required.

**Source A honesty — don't imagine files that don't exist**: if you ran `Read ~/.claude/CLAUDE.md` and the file is empty / one-line `@RTK.md` / not found, **say so** in Source A summary: e.g. "Source A: `~/.claude/CLAUDE.md` 几乎无信号 (1 line `@RTK.md` import)". Don't write source attributions like "你 `~/.claude/CLAUDE.md` 「loud-failure-with-evidence」原则迁移" when you never actually read that content — fabricated source attribution destroys user trust. If Source A is empty, weight Source B (web) + Source H (Karpathy) + Source S (session) heavier and explicitly call it out.

```markdown
## Proposed scenario rule pack — research (7 rules) — CONTENT PREVIEW

**Backends detected** (via `pinrule doctor`): Claude ✓ / Codex ✓ / Cursor ✓ (桌面 Agent)

### Carried over from current library (3 cross-scenario universals)
- [loud-failure-with-evidence] — 完成时附证据
- [read-before-write] — 改前先读
- [non-blocking-parallel] — 非阻塞推进

### New (4 scenario-specific)
- [no-fabricated-citation]
  preference: <full text>
  Source: 源自 your ~/.claude/CLAUDE.md L42 + ICLR 2024 reviewer guidelines

- [assumption-vs-conclusion]
  preference: <full text>
  Source: 源自 nature.com/articles/research-integrity-guide-2023 + Karpathy principle 7

- ...

### Removed from current library (4 — dev-specific, don't apply to research)
- [chinese-plain-no-jargon] — language-style preference, not domain rule
- [no-testset-no-future-leakage] — ML-eval specific
- [long-term-fundamental] — anti-shortcut for code refactoring
- [deep-fix-not-bypass] — pinrule-meta rule for dev work

— mechanism details (keywords + engine checks) come in Phase 2 after you confirm content —
```

### Step 5 (Path B, Phase 1): Content approval — one prompt, not per-rule

```
"以上 7 条规则的**内容**替换你现有规则库, 来源已标注. 用一行回复:
   - '应用' / 'apply' → 内容定下来, 进入 Phase 2 配置机制 (keyword + engine check)
   - '应用但保留 [X / Y]' → 我保留你 call out 的现有规则一起加
   - '换 [Z] 为 [...]' → 我替换某条内容
   - '不要 [W]' → 我去掉某条
   - '追加不替换 / append' → 仅加新规则, 现有全保留 (会超软上限)"
```

Don't ping-pong per-rule. User gives one structured reply, you commit the content list and move to Phase 2.

---

## Phase 2 — Mechanism design + approval (Steps 6-9)

Now that the **rule list is locked**, you design the detection mechanism for each rule. This is pure schema engineering — no more domain debate.

**Note**: backend detection happened in **Step 0.5** (Path B Preflight, before Phase 1). The detection results should already be available — use them directly in Step 7 (coverage table) and Step 11 (closing reminder). If you skipped Step 0.5, go back and run `pinrule doctor` now — DO NOT proceed to Step 6/7 without backend data.

### Step 6 (Path B, Phase 2): Generate `violation_keywords` for each approved rule

For each approved rule, generate 3-8 `violation_keywords`:

- **Format**: "intent-prefix + action" (e.g., `"我直接给你方案"` not `"方案"`)
- Match phrases the user/Agent would actually say *when violating the rule*
- Cap at ~5-8 keywords per rule (more ≠ better; noisy pattern-match)
- Mental test: "If Agent says this exact phrase, did they violate?"

Example for `no-fabricated-user-voice`:
```
violation_keywords: [
  "用户应该会说",
  "典型用户会",
  "假设用户觉得",
  "我猜大部分用户",
  "用户大概会反馈"
]
```

These get scanned in PreToolUse (Write/Edit/Bash content) + Stop hook (Agent response text) — **Layer 1.5 keyword detection works for any rule, no engine check required**.

### Step 7 (Path B, Phase 2): Map each rule to an engine check (semantic pattern matching)

Now evaluate whether each rule semantically matches one of the **8 built-in engine checks**. Engine checks add Layer 2 precision (read tool_input + session_state for joint judgment beyond keyword grep).

**Critical**: don't fabricate function names. Schema validation will reject unknown names. Only the 8 below work:

| Rule semantic pattern | Engine check function | What it detects |
|---|---|---|
| "X before Y" / 「先理解再行动」 | `read_before_write` | Edit/Write tool before Read on same target |
| "claim with evidence" / 「证据 + 老实失败」 | `loud_failure_with_evidence` | Completion words without test_pass / data evidence in session |
| "non-blocking / 长任务期间不 idle" | `non_blocking_parallel` | Sleep / long task without `run_in_background` |
| "keep pushing / no silent stop" | `keep_pushing_no_stop` | Agent silent-stop with pending TODOs |
| "no shortcut / 不糊弄" | `long_term_fundamental` | git `--no-verify` / hardcoded long-hash if-branch / TODO scaffolding |
| "no testset leak / 评测干净" | `no_testset_no_future_leakage` | Eval data backfeeding training / cross-split copying |
| "deep fix not bypass" | `bypass_pinrule_detection` | Bash command writing pinrule internal state |
| "plain language" / 「直白沟通」 | `chinese_plain_no_jargon` | Chinese ratio < 40% / jargon terms |

**Cross-scenario reuse examples** (8 engine checks **partially map** to generic behavior patterns — they don't semantically understand UX research / legal citations / writing outlines, they detect specific operational signals):

- UX scenario 的 `understand-context-before-design` → `read_before_write` (设计前没读已有研究 partially maps to「Edit/Write tool 前没 Read 同 file」—— engine 真检测的是 tool-level 读写顺序，跨场景对应是部分映射不是语义等价)
- Legal scenario 的 `evidence-with-citation` → `loud_failure_with_evidence` (法律意见没附判决引用 partially maps to 「完成 claim + session 缺测试通过 evidence」—— engine 不真验证判决书 citation，只检测 completion-language + missing-evidence 这一层)
- Writing scenario 的 `outline-before-prose` → `read_before_write` (写正文前没列大纲 partially maps —— engine 不懂「大纲」概念，只检测 file 读写顺序)
- Research scenario 的 `validate-before-claim` → `loud_failure_with_evidence` (结论没附实验数据 partially maps to claim-without-evidence operational signal)
- Marketing scenario 的 `data-driven-not-vibes` → `loud_failure_with_evidence` (策略主张没附数据 partially maps)

**Be honest about engine check limits**: `read_before_write` is file-IO-order detection, `loud_failure_with_evidence` is completion-language + session-evidence detection. They don't understand UX research methodology / legal citation standards / writing craft. Most cross-scenario rules end up as `preference-only` (Layer 1 header injection + Layer 1.5 keyword) — that's expected, not a failure.

**If no engine check semantically fits** → leave `violation_checks: []`. The rule still gets header injection (Layer 1) + keyword detection (Layer 1.5), just no Layer 2 precision check. Many cross-scenario rules are fine as `preference-only`.

#### Backend coverage for each engine check

Each engine check fires at different hook event points. Coverage by backend (based on which hook events each backend actually delivers):

| Engine check | Hook event | Claude | Codex | Cursor 桌面 Agent | Cursor CLI |
|---|---|---|---|---|---|
| `read_before_write` | PreToolUse | ✅ | ✅ | ✅ | ✅ |
| `loud_failure_with_evidence` | Stop / afterAgentResponse | ✅ | ✅ | ✅ | ⚠️ silent if transcript_path null |
| `non_blocking_parallel` | PreToolUse (Bash) | ✅ | ✅ | ✅ | ✅ |
| `keep_pushing_no_stop` | Stop | ✅ | ✅ | ✅ | ⚠️ |
| `chinese_plain_no_jargon` | Stop | ✅ | ✅ | ✅ | ⚠️ |
| `long_term_fundamental` | Stop + PreToolUse | ✅ | ✅ | ✅ Bash 路径; Stop 路径 ✅ | Bash ✅ / Stop ⚠️ |
| `no_testset_no_future_leakage` | PreToolUse | ✅ | ✅ | ✅ | ✅ |
| `bypass_pinrule_detection` | PreToolUse | ✅ | ✅ | ✅ | ✅ |

**Read this carefully**:
- **Cursor 桌面 Agent (IDE Composer) = 默认整列 ✅** —— transcript 自动写, 不需要用户开开关. **不要给桌面用户发任何 transcript advisory**, 那是 over-warning.
- **Cursor CLI (`cursor agent` 终端) = 边缘场景, 部分 Stop-hook 类 check ⚠️** —— 这是 future feature, pinrule 当前不补齐 CLI null `transcript_path`. 检测到 CLI 主战场用户时再给警告.
- **Claude / Codex = 整列 ✅** —— 不需要任何 backend-specific advisory.

When assigning engine checks in Step 7, **based on Step 0.5 detected backend**, decide whether each rule's engine check is reliable:
- 桌面 Agent 用户: 8 个 check 全可靠 → 直接 attach 适用的 check
- Cursor CLI 主战场用户 (rare): Stop-hook 类 4 个 check 不稳 → 仍然 attach 但 Step 8 preview 标 ⚠️ + Step 11 末尾建议「主用桌面 Agent」

### Step 8 (Path B, Phase 2): Mechanism preview — full rules with keywords + checks

Show user the *complete* rule pack with mechanism details:

```markdown
## 机制配置 (Phase 2) — 完整规则集

[loud-failure-with-evidence] ✓ engine: loud_failure_with_evidence (保留)
  preference: <text>
  violation_keywords: ["这事搞定了", "已经完成", ...] (保留现有)
  violation_checks: ["loud_failure_with_evidence"]

[no-fabricated-user-voice] preference-only (keyword-detect only)
  preference: <text>
  violation_keywords: ["用户应该会说", "典型用户会", "假设用户觉得", "我猜大部分用户", "用户大概会反馈"]
  violation_checks: []
  Why no engine: 「编造 user voice」是字面违反, keyword 已覆盖, 没有 8 个内建 check 语义匹配

[understand-context-before-design] ✓ engine: read_before_write
  preference: <text>
  violation_keywords: ["看起来是个新需求", "应该不影响别的", "我直接设计就好"]
  violation_checks: ["read_before_write"]
  Why this engine: 「设计前没读已有研究」**partially maps to**「Edit 前没 Read on same file」operational pattern (engine 真检测的是 tool-level 读写顺序, 不真懂 UX research methodology — only useful when context + output 在同 file path)
  Backend coverage: ✅ Claude / ✅ Codex / ✅ Cursor 桌面 (PreToolUse 通用)

[loud-failure-research-claim] ✓ engine: loud_failure_with_evidence
  preference: <text>
  violation_keywords: ["这个研究表明", "数据显示", "结论是"]
  violati

…(truncated)
