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今天更新