Skip to content

Latest commit

 

History

History
180 lines (135 loc) · 5.13 KB

File metadata and controls

180 lines (135 loc) · 5.13 KB

Auto Mode & Safety Classifier

Auto mode lets qcr execute all tool calls without prompting for approval. A 2-stage LLM safety classifier prevents destructive actions from being auto-approved.

Enabling auto mode

# CLI flag
qcr --approval-mode never

# Environment variable
QCR_APPROVAL_MODE=never qcr

# In settings.json
{ "approval_mode": "never" }

In auto mode, read-only tools (file reads, searches, listings) execute immediately. Write and execute tools pass through the safety classifier before running.

How the safety classifier works

The classifier evaluates every non-read-only tool call in three stages:

Stage 0: Pattern match (instant)

Checks the tool name and arguments against always_allow and always_deny glob patterns. If a pattern matches, the decision is instant with no LLM call. always_deny takes priority over always_allow.

Stage 1: Fast check (256 tokens)

A short LLM call with a rules-based XML prompt. The classifier returns one of:

  • ALLOW — safe to execute
  • DENY — blocked with a reason
  • ESCALATE — ambiguous, needs deeper analysis

Stage 2: Deep check (4096 tokens)

Only runs when the fast check returns ESCALATE. Includes recent conversation context so the classifier can judge whether the tool call is proportional to the user's request. Returns ALLOW or DENY (no further escalation).

Fail-open design

If either LLM call fails (network error, timeout, unparseable response), the classifier defaults to ALLOW. The rationale: the user explicitly chose auto mode, so the classifier is a safety net rather than a security boundary.

What gets blocked by default

The fast check's built-in rules deny these patterns:

Category Examples
Destructive shell rm -rf, git push --force, git reset --hard
Database DROP TABLE, DELETE FROM, TRUNCATE
Privilege escalation sudo, su, chmod 777
System kill -9, mkfs, dd, shutdown, reboot
Filesystem DeletePath on system directories or outside CWD

The fast check auto-allows:

Category Examples
Read-only File reads, grep, glob, directory listings
Project writes File writes/edits within the project directory
Safe git add, commit, status, diff, log, branch
Build tools install, build, test, lint

Ambiguous operations (pipes, redirects, network calls, system config changes) are escalated to the deep check.

Configuration

Add a safety_classifier section to settings.json:

{
  "safety_classifier": {
    "enabled": true,
    "model": null,
    "always_allow": [
      "ReadFile", "Glob", "Grep", "Ls", "Now",
      "ToolSearch", "AskUserQuestion", "Thinking",
      "Memory", "TodoWrite"
    ],
    "always_deny": [],
    "custom_rules": []
  }
}

Fields

Field Type Default Description
enabled bool true Turn the classifier on/off. When false, auto mode approves everything.
model string or null null Model override for classifier calls. When null, uses the session's active model.
always_allow string[] (see above) Glob patterns that skip the classifier and are allowed.
always_deny string[] [] Glob patterns that skip the classifier and are denied.
custom_rules string[] [] Extra rule strings injected into the classifier prompt.

Pattern syntax

Patterns match against tool names or tool-with-arguments strings:

{
  "always_allow": ["Read*", "Glob", "Grep"],
  "always_deny": [
    "Shell(*rm -rf*)",
    "Shell(*sudo*)",
    "DeletePath"
  ],
  "custom_rules": [
    "Never allow access to /etc/passwd",
    "Deny any curl command to internal network (192.168.*)"
  ]
}
  • Simple name: "Shell" — exact match on tool name
  • Glob: "Read*" — matches ReadFile, ReadDir, etc.
  • With args: "Shell(*rm -rf*)" — matches tool name + argument content

always_deny is checked before always_allow. If both match the same tool call, the call is denied.

Environment variables

Variable Description
QCR_SAFETY_CLASSIFIER Set to 0 or false to disable the classifier entirely
QCR_SAFETY_CLASSIFIER_MODEL Override the model used for classifier LLM calls
QCR_APPROVAL_MODE Set to never to enable auto mode

Examples

CI pipeline with auto mode

QCR_APPROVAL_MODE=never \
  qcr --print "Run the test suite and fix any failures"

Auto mode with a dedicated classifier model

Use a fast, cheap model for safety checks while keeping a powerful model for the main conversation:

{
  "approval_mode": "never",
  "safety_classifier": {
    "model": "gpt-4o-mini"
  }
}

Lock down destructive operations

{
  "safety_classifier": {
    "always_deny": [
      "Shell(*rm*)",
      "Shell(*git push*)",
      "DeletePath",
      "Shell(*docker rm*)"
    ]
  }
}

Allow specific operations without LLM check

{
  "safety_classifier": {
    "always_allow": [
      "Shell(*cargo test*)",
      "Shell(*npm run*)",
      "WriteFile",
      "EditFile"
    ]
  }
}