Pr To Lint Rule

zernie/vigiles/.claude/skills/pr-to-lint-rule

作者 zernie1d562c69566f無授權條款15 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

Synthesize a recurring code-review rule into a custom lint rule — gated by an independent soundness test that abstains rather than ship a checker it can't prove sound

AI 產生的概覽

把反覆出現的散文式程式碼審查規則合成為自訂 lint 規則,並由獨立健全性測試把關,未通過就棄用。

功能
這個技能接收一條現有 linter 規則無法涵蓋的散文式規則,依流程執行:辨識語言與 linter、先檢查是否已有現成規則可用、對照程式碼庫釐清規則意圖,然後產生自訂規則,以及一個獨立、編碼真實意圖並包含對抗性案例的測試。信任閘門會用該測試執行檢查器,要求精確率與召回率皆為 1.0;通過的規則會被保留並寫入指令檔,外洩的規則則棄用並以散文形式交回。產出包括規則、測試、閘門證據與整合說明,並在寫入任何檔案前先徵求確認。
適用情境
當某條程式碼審查慣例反覆出現、但沒有任何現成 linter 規則可匹配時使用,例如禁止直接從某個套件匯入,或要求對外呼叫必須經過重試包裝。它也是 vigiles 稽核規則圖中自訂規則項目的交接目標。這個技能需明確呼叫,不會自行執行。
執行需求
需要在能辨識出主要語言與 linter(ESLint、Ruff、Pylint、RuboCop、Clippy、Stylelint 或 Go 分析器)的程式碼庫中執行;工具鏈不明確時可能詢問使用者。它會引用外部 linter 參考文件,以及帶有黃金案例與 npm 示範的 rule-enforcer 閘門,本身不附帶指令碼。寫入檔案或修改 spec、CLAUDE.md 前需使用者確認。

Turn a prose rule that no off-the-shelf linter rule matches into a custom lint rule — the opt-in synthesis step. This is the hand-off target of the custom rule (⚙) lane in a vigiles audit rule map: audit maps a rule there when it looks enforceable but nothing off-the-shelf fits. You invoke this skill explicitly; nothing here runs on its own, and installing vigiles never starts synthesizing anything.

The point of this skill is not "write a checker." A model can write a plausible-looking checker in seconds. The point is the discipline that makes the result trustworthy: synthesize the rule and an independent test that encodes the rule's real intent, run the checker against adversarial cases it didn't author, and abstain — hand it back as prose — if it leaks. A checker that matches a rule's surface but not its intent gives false confidence (the measured failure mode: most naively-synthesized checkers silently leak). Shipping a green check nobody should trust is worse than shipping nothing.

Arguments

$ARGUMENTS — a prose rule to enforce. Either a custom rule (⚙) line copied from a vigiles audit report, or free text. Examples:

  • "we keep telling people not to import directly from antd — use our design-system barrel"
  • "people forget to use our custom logger instead of console.log"
  • "wrap outbound API calls in our withRetry helper"
  • "route handlers must go through the withAuth wrapper"

The pipeline

prose rule  → detect language + linter (ask if ambiguous)  → REUSE first: does an off-the-shelf rule already fit? → use it, STOP (no synthesis)  → clarify intent + read the codebase (what exactly is the violation? the fix?)  → SYNTHESIZE: the rule  +  an INDEPENDENT intent-encoding test (adversarial cases)  → TRUST GATE: run the checker on that test; precision AND recall must be 1.0        pass → KEPT     (safe to enforce; wire it in)        leak → ABSTAIN  (hand back as prose; never ship a checker it can't prove sound)

Instructions

Step 1 — Detect the language and toolchain

Read the repo to find the primary language, the linter in use (ESLint, Ruff, Pylint, Clippy, RuboCop, Stylelint…), the test framework, and any existing custom rules (to match conventions). If you cannot confidently pick one — polyglot repo, no linter config, several candidates — ask the user before generating anything.

Step 2 — REUSE before you synthesize (ADOPT > REUSE > SYNTHESIZE)

Synthesis is the last resort, not the first. Before writing any rule:

  1. Check existing plugins / built-in rules. Read the linter reference doc below (the plugin table + no-restricted-* families) — most one-off prohibitions are a config line, not custom code.
  2. Try a built-in construct rule. ESLint no-restricted-syntax / no-restricted-imports, Ruff/Pylint selects, RuboCop cops, etc.
  3. Only synthesize when the rule needs AST analysis, a fix, or options that no existing rule provides.

If an off-the-shelf rule fits, use it and stop — enable it (one config line) and jump to Step 6. That is the strengthen outcome, and it's the better one; don't synthesize a rule when a maintained one exists.

LanguageLinterReference doc
JavaScript/TypeScriptESLint../../../skills/linter-docs/eslint.md
PythonRuff../../../skills/linter-docs/ruff.md
PythonPylint../../../skills/linter-docs/pylint.md
RubyRuboCop../../../skills/linter-docs/rubocop.md
RustClippy../../../skills/linter-docs/clippy.md
CSSStylelint../../../skills/linter-docs/stylelint.md

For Go, generate a golang.org/x/tools/go/analysis analyzer with analysistest tests. For any other language, use the most idiomatic linting approach with test cases and integration notes.

Step 3 — Nail the intent, then read the codebase

Synthesis fails when the checker enforces what's easy to match instead of what the rule means. Before writing anything, pin down:

  • The exact violation. "No hardcoded secrets" is not "a variable named password" — it's apiKey, token, an env-less literal too. "Wrap API calls in retry" needs the real signature of the calls and the wrapper.
  • The fix. What does the compliant form look like, concretely, in this codebase? Read the real files — the helper's import path, its call shape.
  • The clean lookalikes. What looks like a violation but isn't? (the pattern inside a string, a comment, a JSDoc @example; an aliased/namespaced form.)

If any of this is ambiguous — and for anything like "wrap API calls in retry" it usually is — ask the user rather than guessing. A rule built on a guessed intent will fail the gate anyway; asking is cheaper.

Step 4 — Synthesize the rule AND an independent intent test

Write two artifacts:

  1. The rule — prefer AST/keyword analysis over text/substring scanning (text-scan checkers false-positive on the pattern appearing in prose; a name-based checker false-negatives on synonyms). Follow the reference doc's anatomy, fix/suggest, and registration guidance.

  2. An independent test that encodes the INTENT, not the checker's shortcut. This is the trust anchor — write it to the rule's meaning, then seed it with the adversarial cases that break naive synthesis:

    • valid (must NOT flag): the pattern in a string literal, a line comment, a JSDoc/docstring @example; a camelCase identifier that merely contains the keyword (consoleLog); a compliant call that looks close.
    • invalid (MUST flag): every real form of the violation — synonyms (apiKey/token, not just password), the aliased/namespaced form (window.console.log), the wrapped-differently case.

    Do not make the test agree with a shortcut the checker took. If the rule is "no hardcoded secret," the test asserts apiKey is a violation even if your first checker only catches password — so the gate can catch the leak.

Step 5 — The trust gate: precision AND recall must be 1.0

Run the synthesized checker against the Step-4 test (ESLint RuleTester, pytest, analysistest, whatever fits the linter).

  • Pass (every invalid flagged, every valid clean → precision = recall = 1.0): the rule is KEPT — safe to enforce. Continue to Step 6.
  • Leak (any false positive or false negative): the rule is ABSTAINED. Do not wire it in. Report honestly why it leaked (e.g. "matches the pattern in a comment," "misses apiKey") and either (a) hand the rule back as prose, or (b) if you can fix the checker, do so and re-run the gate — but never ship an un-passed checker.

The reference gate lives in rule-enforcer/gate.js (two-stage: self-test + a blind adversarial gold set), the canonical adversarial cases in rule-enforcer/gold/gold.json, and a runnable end-to-end demo (cd rule-enforcer && npm run demo — watch it keep the sound rules and abstain the two leaky ones). Read them for the case shapes and the abstain discipline, then mirror it here; don't reinvent the gate.

Step 6 — Wire a KEPT rule into the instruction file

Only for a rule that passed the gate (or an off-the-shelf rule reused in Step 2).

v2 specs (repo has CLAUDE.md.spec.ts): add an enforce() line and recompile —

typescript
"<rule-id>": enforce("<linter>/<rule-name>", "<why>"),

then npx vigiles compile.

v1 (hand-written CLAUDE.md): append —

markdown
### <Rule title — imperative, concise>
**Enforced by:** `<linter>/<rule-name>`**Why:** <one sentence — the architectural reason>

Step 7 — Present the outcome

Show the user, honestly:

  • Kept rules: the generated files, the gate evidence (the adversarial cases it passed), integration steps, the spec/CLAUDE.md block, and how to verify (run the linter, watch it catch a real violation).
  • Abstained rules: which rule, why it leaked, and that it stays prose — a refused checker is a correct outcome, not a failure to hide.

Then ask before writing any files or editing the spec/CLAUDE.md. Nothing is written for the user automatically.

來源與署名

來源:zernie/vigiles位於.claude/skills/pr-to-lint-rule提交1d562c6

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架

更多來自 zernie/vigiles 的技能

Linter Docs

zernie

Deep linter reference for authoring or debugging a vigiles enforce() rule — plugin tables, AST selectors, type-aware rules, auto-fix, and edge cases for ESLint, Ruff, Pylint, RuboCop, Stylelint, and Clippy. Use when you need the exact rule name or config for a specific linter, not for running a linter. (JVM/Go linters — detekt, ktlint, Checkstyle, golangci-lint — and Cedar have no deep-dive file yet; their reference lives in docs/linter-support.md.)

待分類15今天更新

Debug My Harness

zernie

透過讀取本機 .vigiles/runs.jsonl 飛行記錄帳本來診斷代理框架的異常行為。

AI & Agents15今天更新

Review Docs

zernie

Review the README or a documentation page from several real reader points of view at once. Fans out one parallel reviewer per audience — Claude Code newcomer, power user, plugin/skill author, skeptical senior engineer, non-running decision-maker — each scoring it x/5 and naming concrete, line-level fixes. Use when asked to review, critique, grade, or "get to N/5" the README or any front-door doc, or to check how a doc reads for real users. Not for code review (use /code-review for that).

待分類15今天更新

Adopt Spec

zernie

將現有的手寫 CLAUDE.md 轉換為使用 vigiles 規範函式庫的型別化 CLAUDE.md.spec.ts。

AI & Agents15今天更新

Enforce Rules Format

zernie

驗證專案指令檔案中的規則是否具備正確的強制分類,並修正缺少的分類。

AI & Agents15今天更新

Deep Research

zernie

Use when the user asks to research a topic in depth, map a competitive/market landscape, run a multi-source investigation, or "fan out" parallel research agents — anything where many findings must be gathered and then NOT lost. Enforces durable, detail-preserving research (write full findings to disk; keep a full appendix beside the synthesis).

待分類15今天更新