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
/skillsmenu 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:
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 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:
- If
$ARGUMENTSempty → Path 0 (audit dashboard) - Vocabulary tells: "scenario / 场景 / switch / 切到 / mainly do / 主要做 / replace rule library / 替换规则库" → Path B
- Otherwise → Path A
If genuinely ambiguous, ask once, then proceed. Don't ping-pong.
Path A constraints — do NOT skip any step:
- Refine user's natural language into pinrule's "collaborative agreement" tone (not rule-system tone)
- Format
violation_keywords(if any) in "intent-prefix + action" format (e.g., "I'll skip this" not "skip") - Decide whether to attach
violation_checks(engine-layer hook detection) — this is optional - Test via
pinrule rule previewbefore writing - Confirm with user before calling
pinrule rule add - After adding, report: refined content + test passed + current rule library count + suggest deletions/modifications
Path B: jump to 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"):
- Draft the new JSON first — write the full revised rule to
/tmp/pinrule-rule-<id>.json(keep the originalidso violation history stays linked, unless the rule's purpose genuinely changed) - Preview —
pinrule rule preview --from-json /tmp/pinrule-rule-<id>.jsonto confirm schema + injection text - Atomic-ish swap —
pinrule rule remove <id> && pinrule rule add --from-json /tmp/pinrule-rule-<id>.json(chain with&&so anaddfailure 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\nfor line breaks)violation_keywords— intent-prefix + action format (3-8 entries)violation_checks— pick 0 or 1 of the 8 built-in functionsforce_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:
{ "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:
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"):
pinrule rule add --from-json /tmp/pinrule-new-rule.json
For modifying an existing rule (Step 2 said "modify"):
# 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:
- What was added — show the final JSON (refined from their natural language)
- pinrule tests passed — schema validation + violation_checks existence verified
- Current rule library count — X of soft cap 10 / hard cap 12
- 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.
- 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?"
- If close to soft cap (8+), suggest reviewing existing rules for duplicates/merging. Be concrete: name the specific rule pair that looks redundant ("
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-evidencealready, which partially covers this. But your new request adds specificity: "must attach actual test pass evidence." Let me refine into 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:
- Should the keyword list also include "all set" or "all good"?
- The existing
loud-failure-with-evidencerule 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-evidencein concept (both about evidence). If you find one redundant after a few days of use, consider runningpinrule 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):
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
Yin queries — but flag it back to them: "I'll includeYin 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. 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)preferencetext (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-parallelapply 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.
## 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 nulltranscript_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:
## 机制配置 (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)