Skip to content

test: multi-pass pipeline with linter-rule-judge#162

Draft
gricha wants to merge 9 commits intomainfrom
test/multi-pass-pipeline
Draft

test: multi-pass pipeline with linter-rule-judge#162
gricha wants to merge 9 commits intomainfrom
test/multi-pass-pipeline

Conversation

@gricha
Copy link
Owner

@gricha gricha commented Feb 13, 2026

What

Test PR for warden's multi-pass skill pipeline (getsentry/warden#144).

Points warden at feat/multi-pass-pipeline branch which adds phase-aware execution. Phase-1 skills (security-review, code-simplifier) run first, then phase-2 (linter-rule-judge) receives their findings and proposes deterministic lint rules.

Bait code

src/config/loader.ts has three intentionally bad patterns:

  • eval(expr) -- should trigger no-eval oxlint rule proposal
  • new Function('config', code) -- should trigger no-new-func oxlint rule proposal
  • execSync(`${scriptDir}/${scriptName}`) -- should trigger a custom oxlint plugin proposal

Expected behavior

  1. Phase-1 skills flag the security issues with suggestedFixes
  2. Phase-2 linter-rule-judge reads .oxlintrc.json and oxlint-plugins/, then proposes:
    • Config diffs to enable no-eval and no-new-func
    • A custom plugin for the execSync interpolation pattern

After testing

Revert workflow back to getsentry/warden@v0 and remove bait code.

- 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 <noreply@anthropic.com>
@gricha gricha force-pushed the test/multi-pass-pipeline branch from 669a5ac to ce2dfae Compare February 13, 2026 21:39
gricha and others added 2 commits February 13, 2026 13:44
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(superseded)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(superseded)

Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(superseded)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Repository owner deleted a comment from github-actions bot Feb 13, 2026
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(superseded)

Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(superseded)

Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-actions[bot]

This comment was marked as outdated.

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 <noreply@anthropic.com>
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Repository owner deleted a comment from github-actions bot Feb 14, 2026
Comment on lines +133 to +135
export function evaluateConfigExpression(expr: string): unknown {
return eval(expr);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [QX6-SFD] Arbitrary Code Execution via eval() (high confidence)

The evaluateConfigExpression function uses eval() which allows arbitrary JavaScript code execution. If expr comes from user input, attackers can execute any code.

Suggested fix: Remove eval() entirely. Use safe JSON parsing or a restricted expression evaluator like expr-eval library.

Suggested change
export function evaluateConfigExpression(expr: string): unknown {
return eval(expr);
}
// eval() is unsafe - use JSON.parse() or a safe expression library
throw new Error('evaluateConfigExpression is disabled for security');

Identified by Warden via security-review · critical, high confidence

Comment on lines +137 to +139
export function createDynamicHandler(code: string): Function {
return new Function('config', code);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [H5W-69G] Arbitrary Code Execution via Function Constructor (high confidence)

The createDynamicHandler function uses new Function() which allows arbitrary code execution. If code parameter contains user input, attackers can execute any code.

Suggested fix: Remove new Function() entirely. Use a safe configuration mechanism or predefined handler functions.

Suggested change
export function createDynamicHandler(code: string): Function {
return new Function('config', code);
}
// new Function() is unsafe - use predefined handlers instead
throw new Error('createDynamicHandler is disabled for security');

Identified by Warden via security-review · critical, high confidence

Comment on lines +123 to +130
export async function runConfigScript(scriptName: string, configDir?: string): Promise<string> {
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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [ENX-7BN] Command Injection via Template Literal (high confidence)

The runConfigScript function uses execSync with template literal interpolation. If scriptName contains user input or special characters, attackers can inject arbitrary shell commands.

Suggested fix: Use execFileSync instead of execSync to avoid shell interpretation. Validate scriptName against an allowlist.

Suggested change
export async function runConfigScript(scriptName: string, configDir?: string): Promise<string> {
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;
const { execFileSync } = await import('child_process');
// Validate scriptName is safe (alphanumeric, dash, underscore, .sh only)
if (!/^[a-zA-Z0-9_-]+\.sh$/.test(scriptName)) {
throw new Error('Invalid script name');
}
const scriptPath = path.join(scriptDir, scriptName);
const result = execFileSync(scriptPath, [], {
encoding: 'utf-8',

Identified by Warden via security-review · critical, high confidence

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warden-lint-judge

Warden skill: evaluates first-pass findings and proposes deterministic lint rules that could permanently catch the same patterns. Requires Warden's multi-pass pipeline (phase 2).

Found 3 issues (3 low)

🔵 [JCG-GQ8] no-eval (high confidence)

Add "no-eval": "error" to the rules object in .oxlintrc.json to ban all eval() calls. This prevents arbitrary code execution and catches the pattern on line 134 of src/config/loader.ts.

🔵 [T7D-ACR] no-new-func (high confidence)

Add "no-new-func": "error" to the rules object in .oxlintrc.json to ban new Function() constructor calls. This prevents dynamic code generation and catches the pattern on line 138 of src/config/loader.ts.

🔵 [CFV-NV8] custom: no-execsync-interpolation (high confidence)

Create oxlint-plugins/no-execsync-interpolation.js to detect execSync() calls with template literal arguments containing interpolations (matches AST pattern: CallExpression[callee.name="execSync"][arguments.0.type="TemplateLiteral"][arguments.0.expressions.length>0]). Then add "./oxlint-plugins/no-execsync-interpolation.js" to the jsPlugins array and "perry-custom/no-execsync-interpolation": "error" to the rules object in .oxlintrc.json. This catches shell injection risks like the pattern on line 126 of src/config/loader.ts.

Identified by Warden via warden-lint-judge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant