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 file | Event | Purpose |
|---|---|---|
sanitize-input.js | UserPromptSubmit | Detects and blocks prompt injection |
audit-log.js | All events | Appends structured audit entries |
qa-safety.js | PreToolUse | Blocks 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 code | Meaning |
|---|---|
0 | Prompt is clean - proceed normally |
1 | Soft warning - potentially suspicious pattern detected, but not blocked |
2 | Hard 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>.jsonlEach 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
| Category | Examples |
|---|---|
| Application source edits | Writing/editing .ts, .tsx, .js (outside plugin dirs), .py, .go, .rb, .java |
| Destructive shell commands | rm -rf, git reset --hard, DROP TABLE |
| Privilege escalation | Commands containing sudo, su -, chmod 777 |
| Package installs during test runs | npm install <pkg>, pip install (blocked outside /qa-setup) |
| Secret file writes | Writing 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 *.logDo 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:
# 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: 2See the full test matrix in the Hooks Testing Guide.
