Skip to content

Hooks & Safety Guards

dq-awesomeqa runs three hooks in every supported coding-agent session. They are declared in hooks/hooks.json and require no configuration.


Active hooks

Hook fileEventPurpose
sanitize-input.jsUserPromptSubmitDetects and blocks prompt injection
audit-log.jsAll eventsAppends structured audit entries
qa-safety.jsPreToolUseBlocks dangerous or out-of-scope operations

sanitize-input.js

Trigger: fires before every user message is processed.

Scans the incoming prompt for known injection patterns. Two exit codes:

Exit codeMeaning
0Prompt is clean - proceed normally
1Soft warning - potentially suspicious pattern detected, but not blocked
2Hard block - injection attempt detected, message dropped

If you receive a 2 (hard block), your coding agent will not process the message. Review your prompt and resubmit.


audit-log.js

Trigger: fires on every event (session start, tool call, session end).

Appends a JSONL entry to:

.claude/logs/session-<date>-<id>.jsonl

Each entry records the event type, timestamp, tool name, and tool inputs. Logs are append-only and never modified by the plugin. They are safe to commit to your repository for audit trail purposes.


qa-safety.js

Trigger: fires before every tool call (PreToolUse).

This is the most important hook. It enforces the QA consultant role - dq-awesomeqa reads application code but never modifies it. The hook:

Blocked operations

CategoryExamples
Application source editsWriting/editing .ts, .tsx, .js (outside plugin dirs), .py, .go, .rb, .java
Destructive shell commandsrm -rf, git reset --hard, DROP TABLE
Privilege escalationCommands containing sudo, su -, chmod 777
Package installs during test runsnpm install <pkg>, pip install (blocked outside /qa-setup)
Secret file writesWriting to .env, *.key, *.pem, *secret* paths

Allowed write targets

The hook allows writes only to these locations:

/tmp/                        ← temp working files
/var/folders/                ← macOS temp
qa-reports/                  ← test output artifacts
a11y-artifacts/              ← accessibility scan output
qa-plan.md                   ← QA plan
qa-summary.md                ← QA summary
qa-triage*.md                ← triage documents
qa-coverage*.md              ← coverage documents
qa-exec*.md                  ← execution records
dq-qa.config.json            ← project configuration
hooks/  skills/  .claude/  docs/   ← plugin own files
*.yaml  *.yml  *.json  *.html  *.md  *.txt  *.csv  *.log

Do not work around the hook

If a test scenario requires elevated permissions or source code changes, stop and report it to the developer. Do not attempt to bypass qa-safety.js.


Testing hooks locally

You can test the safety hook without starting a Claude session by piping JSON directly:

bash
# Should ALLOW - writing a YAML file
echo '{
  "tool_name": "Write",
  "tool_input": {
    "file_path": "./load-tests/dq-nbomber.yaml",
    "content": "version: 1"
  }
}' | node hooks/qa-safety.js
echo "Exit: $?"   # expect: 0

# Should BLOCK - editing a TypeScript source file
echo '{
  "tool_name": "Edit",
  "tool_input": {
    "file_path": "./src/app/auth.ts",
    "old_string": "foo",
    "new_string": "bar"
  }
}' | node hooks/qa-safety.js
echo "Exit: $?"   # expect: 2

See the full test matrix in the Hooks Testing Guide.

Released under the AGPL-3.0 License.