From ce2dfaee5deafe3c5ed27fc73537915351554320 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:35:00 -0800 Subject: [PATCH 1/9] test: multi-pass pipeline with linter-rule-judge - Point warden at feat/multi-pass-pipeline branch - Add phase-2 linter-rule-judge skill - Add bait code with eval(), new Function(), execSync interpolation Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 75 +++++++++++++++++++++++ .github/workflows/warden.yml | 46 +++++++++++++- src/config/loader.ts | 18 ++++++ warden.toml | 11 ++-- 4 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 .agents/skills/linter-rule-judge/SKILL.md diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md new file mode 100644 index 0000000..8b59911 --- /dev/null +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -0,0 +1,75 @@ +--- +name: linter-rule-judge +description: Generate lint rules that replace AI findings with deterministic checks +allowed-tools: Read Grep Glob +--- + +# Linter Rule Judge + +You are a second-pass skill. Your job: turn AI findings into deterministic lint rules. + +The bar is high. Only propose a rule when you can guarantee it catches the exact pattern through AST structure, not heuristics. A rule that fires on `eval(anything)` is deterministic. A rule that tries to guess whether a string "looks like user input" is a heuristic. Only the first kind belongs here. + +## Step 1: Detect the linter + +Before evaluating any findings, determine what linter system the project uses. Use `Glob` and `Read` to check for: + +- `.oxlintrc.json` / `oxlint.json` (oxlint) +- `.eslintrc.*` / `eslint.config.*` / `"eslintConfig"` in package.json (eslint) +- `clippy.toml` / `.clippy.toml` (Rust clippy) +- `.pylintrc` / `pyproject.toml` with `[tool.pylint]` (pylint) +- `.flake8` / `setup.cfg` with `[flake8]` (flake8) +- `biome.json` / `biome.jsonc` (biome) + +Also check whether the linter supports custom/plugin rules: +- oxlint: check for `jsPlugins` in config and an existing plugins directory +- eslint: check for local plugins or `eslint-plugin-*` deps +- biome: no custom rule support, existing rules only + +If the project has no linter, return an empty findings array. You cannot propose rules for a tool that doesn't exist. + +## Step 2: Evaluate prior findings + +For each prior finding that has a `suggestedFix`, ask: can this exact pattern be caught by a deterministic AST check in the linter we found? + +**Deterministic means:** +- The rule matches a specific syntactic pattern in the AST (node type, property name, call signature) +- Zero or near-zero false positives -- if the AST matches, the code is wrong +- No guessing about intent, data flow, variable contents, or runtime behavior +- Examples: banning `eval()`, requiring `===` over `==`, disallowing `execSync` with template literal arguments, flagging `new Function()` calls + +**Not deterministic (skip these):** +- "This variable might contain user input" (data flow analysis) +- "This function name suggests it handles sensitive data" (naming heuristic) +- "This pattern is usually a bug" (probabilistic) +- Anything that requires understanding what a variable contains at runtime + +**Only report if ALL of these are true:** +1. You can identify a specific existing rule by name, OR you can write a complete working custom rule +2. The rule is deterministic: it matches AST structure, not heuristics +3. The project's linter actually supports this + +## What to skip silently + +- Findings without `suggestedFix` +- Patterns that need type information the linter can't access, cross-file context, or runtime knowledge +- Patterns where the rule would need to guess or use heuristics +- Cases where you're not confident the rule is correct and complete + +Return an empty findings array when nothing qualifies. That's the expected common case. + +## Output format + +For existing rules: +- **title**: The rule name (e.g., `no-eval`) +- **severity**: `low` +- **description**: One sentence: what AST pattern it matches +- **suggestedFix**: A diff enabling the rule in the project's linter config +- **location**: Same as the original finding + +For custom rules: +- **title**: `custom: ` (e.g., `custom: no-execsync-interpolation`) +- **severity**: `low` +- **description**: One sentence: what AST pattern it matches +- **suggestedFix**: The complete rule implementation file AND the config diff to wire it up. Match the conventions of existing custom rules in the project. +- **location**: Same as the original finding diff --git a/.github/workflows/warden.yml b/.github/workflows/warden.yml index 3a42e0a..af1c8e6 100644 --- a/.github/workflows/warden.yml +++ b/.github/workflows/warden.yml @@ -18,6 +18,50 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Strip newlines from OAuth token run: echo "CLAUDE_CODE_OAUTH_TOKEN=$(printf '%s' "$CLAUDE_CODE_OAUTH_TOKEN" | tr -d '\n\r\t ')" >> "$GITHUB_ENV" - - uses: getsentry/warden@v0 + + # Build warden from source (testing feat/multi-pass-pipeline) + - uses: actions/checkout@v4 + with: + repository: getsentry/warden + ref: feat/multi-pass-pipeline + path: .warden-src + + - uses: pnpm/action-setup@v4 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: .warden-src/pnpm-lock.yaml + + - name: Build warden from source + run: cd .warden-src && pnpm install --frozen-lockfile && pnpm build || true && pnpm build:action + + - name: Install Claude Code CLI + run: | + CLAUDE_CODE_VERSION="2.1.32" + for attempt in 1 2 3; do + if curl -fsSL https://claude.ai/install.sh | bash -s -- "$CLAUDE_CODE_VERSION"; then break; fi + [ $attempt -eq 3 ] && exit 1 + sleep 5 + done + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + + - name: Run Warden + id: warden + env: + INPUT_GITHUB_TOKEN: ${{ github.token }} + INPUT_CONFIG_PATH: warden.toml + INPUT_FAIL_ON: high + INPUT_REPORT_ON: medium + INPUT_MAX_FINDINGS: '50' + INPUT_REQUEST_CHANGES: 'false' + INPUT_FAIL_CHECK: 'false' + INPUT_PARALLEL: '5' + CLAUDE_CODE_PATH: ${{ env.HOME }}/.local/bin/claude + run: node .warden-src/dist/action/index.js diff --git a/src/config/loader.ts b/src/config/loader.ts index aa43de8..d88148a 100644 --- a/src/config/loader.ts +++ b/src/config/loader.ts @@ -120,6 +120,24 @@ export async function loadAgentConfig(configDir?: string): Promise } } +export async function runConfigScript(scriptName: string, configDir?: string): Promise { + const { execSync } = await import('child_process'); + const scriptDir = path.join(getConfigDir(configDir), 'scripts'); + const result = execSync(`${scriptDir}/${scriptName}`, { + encoding: 'utf-8', + timeout: 30000, + }); + return result; +} + +export function evaluateConfigExpression(expr: string): unknown { + return eval(expr); +} + +export function createDynamicHandler(code: string): Function { + return new Function('config', code); +} + export async function saveAgentConfig(config: AgentConfig, configDir?: string): Promise { const dir = getConfigDir(configDir); await ensureConfigDir(dir); diff --git a/warden.toml b/warden.toml index de18d40..3f3d1fc 100644 --- a/warden.toml +++ b/warden.toml @@ -16,9 +16,9 @@ actions = ["opened", "synchronize", "reopened"] type = "local" [[skills]] -name = "react-best-practices" -paths = ["**/*.tsx", "**/*.jsx"] -remote = "vercel-labs/agent-skills" +name = "code-simplifier" +paths = ["src/**", "web/**", "mobile/**"] +remote = "getsentry/skills" [[skills.triggers]] type = "pull_request" @@ -28,9 +28,8 @@ actions = ["opened", "synchronize", "reopened"] type = "local" [[skills]] -name = "code-simplifier" -paths = ["src/**", "web/**", "mobile/**"] -remote = "getsentry/skills" +name = "linter-rule-judge" +phase = 2 [[skills.triggers]] type = "pull_request" From 27a874e9292f8595109dd0b25b181fe6eb60f64f Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:44:42 -0800 Subject: [PATCH 2/9] fix: set reportOn=low for linter-rule-judge Phase-2 linter-rule-judge findings use severity=low by design (they're suggestions, not bugs). Without per-skill reportOn, the global report-on=medium threshold filters them out of PR comments. Co-Authored-By: Claude Opus 4.6 --- warden.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/warden.toml b/warden.toml index 3f3d1fc..c401596 100644 --- a/warden.toml +++ b/warden.toml @@ -30,6 +30,7 @@ type = "local" [[skills]] name = "linter-rule-judge" phase = 2 +reportOn = "low" [[skills.triggers]] type = "pull_request" From 40efe7f3aa630bf758f745045c6c17ba1c57c6e6 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:49:46 -0800 Subject: [PATCH 3/9] fix: omit location from linter-rule-judge findings Lint rule suggestions should appear as top-level comments, not inline on source code lines they don't relate to. Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md index 8b59911..9951c2f 100644 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -60,16 +60,16 @@ Return an empty findings array when nothing qualifies. That's the expected commo ## Output format +**Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. + For existing rules: - **title**: The rule name (e.g., `no-eval`) - **severity**: `low` - **description**: One sentence: what AST pattern it matches -- **suggestedFix**: A diff enabling the rule in the project's linter config -- **location**: Same as the original finding +- **suggestedFix**: A diff enabling the rule in the project's linter config file For custom rules: - **title**: `custom: ` (e.g., `custom: no-execsync-interpolation`) - **severity**: `low` - **description**: One sentence: what AST pattern it matches - **suggestedFix**: The complete rule implementation file AND the config diff to wire it up. Match the conventions of existing custom rules in the project. -- **location**: Same as the original finding From 994d9f564b99bd613fa54d183b2c05ec984dd5b7 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:43:33 -0800 Subject: [PATCH 4/9] update linter-rule-judge: description as primary output Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md index 9951c2f..09bf3b1 100644 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -62,14 +62,18 @@ Return an empty findings array when nothing qualifies. That's the expected commo **Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. +**The `description` is the primary output.** It must be self-contained and actionable: tell the developer exactly what to do, which config file to change, and what rule to enable or create. Write it so someone reading a PR comment knows the next step without seeing the diff. Example: "Enable the `no-eval` rule in `.oxlintrc.json` under `rules` to ban all `eval()` calls. Run `warden --fix` locally to apply." + +The `suggestedFix` carries the machine-readable diff for local application via `warden --fix`. It is not shown in PR comments. + For existing rules: - **title**: The rule name (e.g., `no-eval`) - **severity**: `low` -- **description**: One sentence: what AST pattern it matches +- **description**: What the rule catches, which config file to change, and how. Actionable on its own. - **suggestedFix**: A diff enabling the rule in the project's linter config file For custom rules: - **title**: `custom: ` (e.g., `custom: no-execsync-interpolation`) - **severity**: `low` -- **description**: One sentence: what AST pattern it matches +- **description**: What AST pattern the rule matches, which files to create/modify, and how to wire it up. Actionable on its own. - **suggestedFix**: The complete rule implementation file AND the config diff to wire it up. Match the conventions of existing custom rules in the project. From 6685e7d27b65076bae2b6652f3196b97d50b3ca1 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:53:21 -0800 Subject: [PATCH 5/9] update linter-rule-judge: add summary header guidance Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md index 09bf3b1..2baf428 100644 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -60,9 +60,11 @@ Return an empty findings array when nothing qualifies. That's the expected commo ## Output format +**Set the report `summary`** to a short framing paragraph. This appears as a header on the PR comment. It should explain that these are long-term improvements the developer can adopt, and suggest prompting a local agent to apply them. Example: "Warden identified lint rules that could permanently catch patterns flagged in this review. To apply, prompt your local agent with the instructions below, or run `warden --fix` locally." + **Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. -**The `description` is the primary output.** It must be self-contained and actionable: tell the developer exactly what to do, which config file to change, and what rule to enable or create. Write it so someone reading a PR comment knows the next step without seeing the diff. Example: "Enable the `no-eval` rule in `.oxlintrc.json` under `rules` to ban all `eval()` calls. Run `warden --fix` locally to apply." +**The `description` is the primary output.** It must be self-contained and actionable: tell the developer exactly what to do, which config file to change, and what rule to enable or create. Write it so someone reading a PR comment knows the next step without seeing the diff. Example: "Enable the `no-eval` rule in `.oxlintrc.json` under `rules` to ban all `eval()` calls." The `suggestedFix` carries the machine-readable diff for local application via `warden --fix`. It is not shown in PR comments. From 0439acf9ebfcab827495ccc1e97795a3de0e2bdd Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:58:06 -0800 Subject: [PATCH 6/9] update linter-rule-judge: description as framing text Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md index 2baf428..aa0ac1f 100644 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -1,6 +1,6 @@ --- name: linter-rule-judge -description: Generate lint rules that replace AI findings with deterministic checks +description: Warden identified lint rules that could permanently catch patterns flagged in this review. To apply, prompt your local agent with the instructions below or run `warden --fix` locally. allowed-tools: Read Grep Glob --- @@ -60,8 +60,6 @@ Return an empty findings array when nothing qualifies. That's the expected commo ## Output format -**Set the report `summary`** to a short framing paragraph. This appears as a header on the PR comment. It should explain that these are long-term improvements the developer can adopt, and suggest prompting a local agent to apply them. Example: "Warden identified lint rules that could permanently catch patterns flagged in this review. To apply, prompt your local agent with the instructions below, or run `warden --fix` locally." - **Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. **The `description` is the primary output.** It must be self-contained and actionable: tell the developer exactly what to do, which config file to change, and what rule to enable or create. Write it so someone reading a PR comment knows the next step without seeing the diff. Example: "Enable the `no-eval` rule in `.oxlintrc.json` under `rules` to ban all `eval()` calls." From c8098fbdf5c28c9422681b3c7e004779e8e85679 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:04:40 -0800 Subject: [PATCH 7/9] update linter-rule-judge: agent-promptable descriptions Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md index aa0ac1f..965edb5 100644 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ b/.agents/skills/linter-rule-judge/SKILL.md @@ -1,6 +1,6 @@ --- name: linter-rule-judge -description: Warden identified lint rules that could permanently catch patterns flagged in this review. To apply, prompt your local agent with the instructions below or run `warden --fix` locally. +description: Warden identified lint rules that could permanently catch patterns flagged in this review. These target linter config and plugin files outside this PR, so GitHub can't propose them as inline suggestions. To apply, copy the prompt for each rule below to your local coding agent, or run `warden --fix` locally. allowed-tools: Read Grep Glob --- @@ -62,18 +62,18 @@ Return an empty findings array when nothing qualifies. That's the expected commo **Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. -**The `description` is the primary output.** It must be self-contained and actionable: tell the developer exactly what to do, which config file to change, and what rule to enable or create. Write it so someone reading a PR comment knows the next step without seeing the diff. Example: "Enable the `no-eval` rule in `.oxlintrc.json` under `rules` to ban all `eval()` calls." +**The `description` is the primary output.** Write each finding's description as a prompt you could copy-paste directly into a local coding agent. It should be a clear, complete instruction that an agent can act on without additional context. Example: "Add `\"no-eval\": \"error\"` to the `rules` object in `.oxlintrc.json` to ban all `eval()` calls." The `suggestedFix` carries the machine-readable diff for local application via `warden --fix`. It is not shown in PR comments. For existing rules: - **title**: The rule name (e.g., `no-eval`) - **severity**: `low` -- **description**: What the rule catches, which config file to change, and how. Actionable on its own. +- **description**: A copy-pasteable prompt: which config file to edit, what to add, and why. - **suggestedFix**: A diff enabling the rule in the project's linter config file For custom rules: - **title**: `custom: ` (e.g., `custom: no-execsync-interpolation`) - **severity**: `low` -- **description**: What AST pattern the rule matches, which files to create/modify, and how to wire it up. Actionable on its own. +- **description**: A copy-pasteable prompt: what plugin file to create, what AST pattern it matches, and how to wire it into the linter config. - **suggestedFix**: The complete rule implementation file AND the config diff to wire it up. Match the conventions of existing custom rules in the project. From 2ea8cbfd7aa74d2cc5546ad32477001da4d360c7 Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:16:53 -0800 Subject: [PATCH 8/9] trigger: re-run warden with summary fix Co-Authored-By: Claude Opus 4.6 From 1ccc8290084d24da996ee93fe23d1e07067470cc Mon Sep 17 00:00:00 2001 From: Greg Pstrucha <875316+gricha@users.noreply.github.com> Date: Fri, 13 Feb 2026 17:04:46 -0800 Subject: [PATCH 9/9] use remote warden-lint-judge with scope = "report" Replace local linter-rule-judge skill with the remote warden-lint-judge from getsentry/skills. Use scope = "report" (report-scoped execution) instead of phase = 2, so the skill runs as a single SDK call on all prior findings. Co-Authored-By: Claude Opus 4.6 --- .agents/skills/linter-rule-judge/SKILL.md | 79 ----------------------- warden.toml | 5 +- 2 files changed, 3 insertions(+), 81 deletions(-) delete mode 100644 .agents/skills/linter-rule-judge/SKILL.md diff --git a/.agents/skills/linter-rule-judge/SKILL.md b/.agents/skills/linter-rule-judge/SKILL.md deleted file mode 100644 index 965edb5..0000000 --- a/.agents/skills/linter-rule-judge/SKILL.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -name: linter-rule-judge -description: Warden identified lint rules that could permanently catch patterns flagged in this review. These target linter config and plugin files outside this PR, so GitHub can't propose them as inline suggestions. To apply, copy the prompt for each rule below to your local coding agent, or run `warden --fix` locally. -allowed-tools: Read Grep Glob ---- - -# Linter Rule Judge - -You are a second-pass skill. Your job: turn AI findings into deterministic lint rules. - -The bar is high. Only propose a rule when you can guarantee it catches the exact pattern through AST structure, not heuristics. A rule that fires on `eval(anything)` is deterministic. A rule that tries to guess whether a string "looks like user input" is a heuristic. Only the first kind belongs here. - -## Step 1: Detect the linter - -Before evaluating any findings, determine what linter system the project uses. Use `Glob` and `Read` to check for: - -- `.oxlintrc.json` / `oxlint.json` (oxlint) -- `.eslintrc.*` / `eslint.config.*` / `"eslintConfig"` in package.json (eslint) -- `clippy.toml` / `.clippy.toml` (Rust clippy) -- `.pylintrc` / `pyproject.toml` with `[tool.pylint]` (pylint) -- `.flake8` / `setup.cfg` with `[flake8]` (flake8) -- `biome.json` / `biome.jsonc` (biome) - -Also check whether the linter supports custom/plugin rules: -- oxlint: check for `jsPlugins` in config and an existing plugins directory -- eslint: check for local plugins or `eslint-plugin-*` deps -- biome: no custom rule support, existing rules only - -If the project has no linter, return an empty findings array. You cannot propose rules for a tool that doesn't exist. - -## Step 2: Evaluate prior findings - -For each prior finding that has a `suggestedFix`, ask: can this exact pattern be caught by a deterministic AST check in the linter we found? - -**Deterministic means:** -- The rule matches a specific syntactic pattern in the AST (node type, property name, call signature) -- Zero or near-zero false positives -- if the AST matches, the code is wrong -- No guessing about intent, data flow, variable contents, or runtime behavior -- Examples: banning `eval()`, requiring `===` over `==`, disallowing `execSync` with template literal arguments, flagging `new Function()` calls - -**Not deterministic (skip these):** -- "This variable might contain user input" (data flow analysis) -- "This function name suggests it handles sensitive data" (naming heuristic) -- "This pattern is usually a bug" (probabilistic) -- Anything that requires understanding what a variable contains at runtime - -**Only report if ALL of these are true:** -1. You can identify a specific existing rule by name, OR you can write a complete working custom rule -2. The rule is deterministic: it matches AST structure, not heuristics -3. The project's linter actually supports this - -## What to skip silently - -- Findings without `suggestedFix` -- Patterns that need type information the linter can't access, cross-file context, or runtime knowledge -- Patterns where the rule would need to guess or use heuristics -- Cases where you're not confident the rule is correct and complete - -Return an empty findings array when nothing qualifies. That's the expected common case. - -## Output format - -**Do NOT set a `location` field.** These findings target linter config and plugin files, not the source code where the original issue was found. Omitting location ensures they appear as top-level review comments, not inline on unrelated source lines. - -**The `description` is the primary output.** Write each finding's description as a prompt you could copy-paste directly into a local coding agent. It should be a clear, complete instruction that an agent can act on without additional context. Example: "Add `\"no-eval\": \"error\"` to the `rules` object in `.oxlintrc.json` to ban all `eval()` calls." - -The `suggestedFix` carries the machine-readable diff for local application via `warden --fix`. It is not shown in PR comments. - -For existing rules: -- **title**: The rule name (e.g., `no-eval`) -- **severity**: `low` -- **description**: A copy-pasteable prompt: which config file to edit, what to add, and why. -- **suggestedFix**: A diff enabling the rule in the project's linter config file - -For custom rules: -- **title**: `custom: ` (e.g., `custom: no-execsync-interpolation`) -- **severity**: `low` -- **description**: A copy-pasteable prompt: what plugin file to create, what AST pattern it matches, and how to wire it into the linter config. -- **suggestedFix**: The complete rule implementation file AND the config diff to wire it up. Match the conventions of existing custom rules in the project. diff --git a/warden.toml b/warden.toml index c401596..739e2f0 100644 --- a/warden.toml +++ b/warden.toml @@ -28,8 +28,9 @@ actions = ["opened", "synchronize", "reopened"] type = "local" [[skills]] -name = "linter-rule-judge" -phase = 2 +name = "warden-lint-judge" +remote = "getsentry/skills" +scope = "report" reportOn = "low" [[skills.triggers]]