Introduction

In the DSH plugin ecosystem, it is sometimes necessary to enforce a specific output format for the model, such as prohibiting full-width parentheses. The dsh-write-rule-guard plugin fulfills this requirement by intercepting content before it is written.

Plugin Overview

Maintained by betterer, categorized as admin-security, and released under the MIT license. The plugin is injected via cordis configuration, by default blocks full-width parentheses [\uFF08\uFF09], and supports custom regular-expression rules.

Core Features

  • Content Interception: Intercepts write operations from tools such as edit, write, edit_remote, and write_remote, and checks their content against configured regular-expression rules.
  • State-Machine Control: When an interception rule matches, the current turn’s pwsh is disabled to prevent the model from using pwsh as a workaround.
  • State Recovery: After a write tool executes successfully, the pwsh disable state is lifted; at the end of the turn, permission is restored.
  • Utility Functions: Provides utility functions such as compilePattern and findMatches for handling regular-expression matching.

Installation and Activation

Install the plugin with the following command:

dsh plugin --profile web add github:better-er/dsh-write-rule-guard

After installation, the plugin injects default configuration through cordis.patch.yml, and takes effect after restarting DSH web.

Configuration

The plugin’s configuration file is located at ~/.dsh/profiles/web/cordis.patch.yml. By overriding the config field, you can adjust interception rules, disable messages, and other settings.

Configuration Items:
- enabled: whether to enable interception (default true).
- rules: list of rules, including pattern (regular expression), message (interception message), and enabled (toggle).
- extraTools: list of additional tools to intercept; defaults include edit_remote and write_remote from dsh-remote-file-system.
- pwshMessage: interception message used when the pwsh disable state is active; supports the {reason} placeholder.
- joiner: separator used when multiple rules match.

Configuration Example:

- id: dsh-write-rule-guard
  config:
    enabled: true
    pwshMessage: '本次写入未遵循用户偏好,已被用户拒绝写入。'
    rules:
      - enabled: true
        pattern: '[\uFF08\uFF09]'
        message: '本次写入未遵循用户偏好,已被用户拒绝写入。请修改为不使用括号的描述方式。行:{lines};文件:{file}'
    extraTools:
      - name: edit_remote
        contentKey: new_string
      - name: write_remote
        contentKey: content

Use Cases and Notes

  • Use Cases: Scenarios where format constraints must be enforced when editing files or writing content, such as prohibiting specific characters.
  • Environment Requirements: Node.js version must be >= 26.3.1, and the plugin depends on @deepseek-ai/dsh.
  • Known Limitation: After a successful interception, only the current turn’s pwsh is disabled. If a write tool (such as edit or write) executes successfully, the state machine lifts the pwsh disable state. This means the model may bypass the guard through a single successful write, then use pwsh again to write non-compliant content in later operations. This behavior is an intentional trade-off and cannot prevent bypass attempts after the disable state is lifted by a successful write.

Exported Utilities

The plugin exports the following utility functions:
- compilePattern(pattern): compiles a user-supplied regular expression; returns null if it is invalid.
- findMatches(content, pattern): scans text and returns a list of match positions.
- collectLines(hits): extracts unique line numbers where matches occurred.
- fillMessage(template, ctx): substitutes placeholders in an error message.
- buildReason(message, file, hits, pattern): constructs a single-line rejection reason for one rule.