Skip to content

feat: add script-guards plugin for runtime script prevention#189

Merged
JacobPEvans merged 5 commits intomainfrom
feat/script-guards
Mar 29, 2026
Merged

feat: add script-guards plugin for runtime script prevention#189
JacobPEvans merged 5 commits intomainfrom
feat/script-guards

Conversation

@JacobPEvans
Copy link
Copy Markdown
Owner

@JacobPEvans JacobPEvans commented Mar 26, 2026

PR #189: Script Guards Plugin

Summary

New script-guards plugin that enforces the direct-execution rule via runtime
PreToolUse and UserPromptSubmit hooks. Prevents script generation at tool
invocation time — the first layer of defense for the multi-layered
script-prevention strategy.

Covers:

  • Write: Fast pattern check + local model evaluation (blocks generated
    scripts outside /scripts/)
  • Edit: Inline script detection in Nix and YAML files (>3 lines bash in
    .nix, >5 lines in run blocks)
  • Bash: File-writing patterns (heredocs, redirects) that generate scripts
  • UserPromptSubmit: Injects "research first" reminder before implementation
    prompts

Changes

New plugin: script-guards/ with 4 shell scripts (299 lines added)

Scripts

  • write-script-guard.sh — Two-stage Write protection:

    • Fast check: pattern match for bash/python/ruby/perl files
    • Deep check: local Qwen3.5-27B evaluation if pattern matches
    • Allows writes to /scripts/ and other safe paths
  • inline-script-guard.sh — Detects scripts embedded in config files:

    • Blocks >3-line bash in .nix files
    • Blocks >5-line bash in YAML run blocks
    • Uses indentation-aware awk for accurate line counting
  • bash-script-guard.sh — Blocks file-writing patterns:

    • Heredocs (<< EOF)
    • Output redirects (>, >>)
    • Pipe to tee, cat, or shell
  • research-reminder.sh — Injects system message on UserPromptSubmit:

    • Reminds about existing tools before new implementations
    • Suppressed on follow-up prompts in same thread

Technical Details

  • BSD/macOS portability: Fixed POSIX character classes
    ([[:space:]] instead of \s)
  • Code simplification: Case statements for keyword matching, dedicated deny
    helper function
  • Optimization: grep -c for line counting where applicable
  • Robustness: Tilde path expansion for file existence checks, proper
    quoting

Related Issues

Addresses part of the multi-layered script-prevention defense (see #19 for
orchestrator philosophy update). Related to #20 (agent-teams-guard).

Test Plan

  • Write a .sh file outside scripts/ → blocked
  • Write a .sh file inside scripts/ → allowed
  • Edit .nix file with >3 lines of bash → blocked
  • Edit .yml file with >5 line run block → blocked
  • cat > test.py via Bash → blocked
  • git status via Bash → allowed
  • Type implementation prompt → see research reminder

Commits: 6 total (feat + 5 fix commits for review feedback, POSIX
compatibility, simplification, and awk improvements)

Copilot AI review requested due to automatic review settings March 26, 2026 15:09
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the 'script-guards' plugin, which implements a series of hooks to prevent unnecessary script generation and enforce a research-first approach. The implementation includes guards against script creation via Bash redirects, complex inline logic in Nix and YAML files, and a two-stage verification for the Write tool that utilizes a local MLX model for nuanced evaluation. A security concern was identified in the directory validation logic of the write-script-guard.sh script, where a permissive substring match could allow unauthorized script placement; a more restrictive top-level directory check was suggested to address this.

The /plugin entry lacked a trailing slash, meaning it would match
unintended paths like /pluginable/ or /plugin-foo/. Changed to
/plugins/ which is more precise and covers the intended use case.

(claude)
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new script-guards Claude Code plugin that enforces runtime “no new scripts” policies by inspecting tool calls (Write/Edit/Bash) and injecting a research-first reminder on implementation-oriented prompts. This fits alongside the existing hook-based guard plugins (e.g., git-guards, content-guards) as another runtime enforcement layer.

Changes:

  • Introduces script-guards/hooks/hooks.json wiring PreToolUse hooks for Write/Edit/Bash plus a UserPromptSubmit reminder hook.
  • Adds three blocking guard scripts (write-script-guard.sh, inline-script-guard.sh, bash-script-guard.sh) and a non-blocking reminder script (research-reminder.sh).
  • Adds the plugin manifest at script-guards/.claude-plugin/plugin.json.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
script-guards/scripts/write-script-guard.sh Two-stage guard for script-like Write operations; allowlists known dirs + optional local-model decision.
script-guards/scripts/inline-script-guard.sh Blocks complex inline shell in .nix and workflow YAML edits based on heuristics/line counts.
script-guards/scripts/bash-script-guard.sh Blocks Bash commands that appear to write scripts (redirects/heredocs) and some chmod patterns.
script-guards/scripts/research-reminder.sh Injects a system message on prompts containing implementation keywords.
script-guards/hooks/hooks.json Registers the new scripts as Claude hooks for PreToolUse/UserPromptSubmit.
script-guards/.claude-plugin/plugin.json Declares the new plugin metadata.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- bash-script-guard: remove redundant alternation in redirect regex
  (>>?|> simplified to >>? since >>? already matches both > and >>)
- research-reminder: replace per-keyword loop with single grep -wE
  alternation (14 grep processes reduced to 1)

(claude)
Replace GNU-only \s/\S with POSIX [[:space:]]/[^[:space:]] in all
grep and sed patterns for macOS BSD tool compatibility. Simplify
write-script-guard extension/directory matching with case statements,
replace per-line grep loop with grep -c in inline-script-guard, extract
deny helper in bash-script-guard, and use grep -i instead of
tr-lowercasing in research-reminder. Scope heredoc check to script file
extensions only (was blocking all cat << patterns).

(claude)
…L indentation

- Add ~ → $HOME path expansion in write-script-guard before existence check
- Replace sed-based YAML run-block counting with indentation-aware awk parser
  that correctly handles indented steps in GitHub Actions workflows
- Add RLENGTH to cspell dictionary (awk built-in variable)

(claude)
@JacobPEvans JacobPEvans merged commit 7f32cb2 into main Mar 29, 2026
5 checks passed
@JacobPEvans JacobPEvans deleted the feat/script-guards branch March 29, 2026 17:10
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.

2 participants