- Add get_anomaly_attr() helper that handles both dict and object
anomalies. The SDK's send_message() returns dicts, so getattr()
was silently returning defaults -- critical blocking never triggered.
- Fix field name: "detail" -> "details" (matches SDK schema).
- Make fail-open/fail-closed configurable via INSAITS_FAIL_MODE env var
(defaults to "open" for backward compatibility).
- Include exception type name in fail-open log for diagnostics.
- Normalize severity comparison with .upper() for case-insensitive matching.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cubic-dev-ai P2: dev_mode now defaults to "false" (strict mode).
Users opt in to dev mode by setting INSAITS_DEV_MODE=true.
cubic-dev-ai P2: Move null-status check above stdout/stderr writes
in wrapper so partial/corrupt output is never leaked. Pass through
original raw input on signal kill, matching the result.error path.
coderabbit major: Wrap insAItsMonitor() and send_message() in
try/except so SDK errors don't crash the hook. Logs warning and
exits 0 (fail-open) on exception.
coderabbit nitpick: write_audit now creates a new dict (enriched)
instead of mutating the caller's event dict.
coderabbit nitpick: Extract magic numbers to named constants:
MIN_CONTENT_LENGTH=10, MAX_SCAN_LENGTH=4000, DEFAULT_MODEL.
Also: added env var documentation to module docstring.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Defaults to true (no API key needed) but can be disabled by setting
INSAITS_DEV_MODE=false for production deployments with an API key.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
P1: Log non-ENOENT spawn errors (timeout, signal kill) to stderr
instead of silently exiting 0. Separate handling for result.error
and null result.status so users know when the security monitor
failed to run.
P1: Remove "async": true from hooks.json — async hooks run in the
background and cannot block tool execution. The security hook needs
to be synchronous so exit(2) actually prevents credential exposure
and other critical findings from proceeding.
P2: Remove dead tool_response/tool_result code from extract_content.
In a PreToolUse hook the tool hasn't executed yet, so tool_response
is never populated. Removed the variable and the unreachable branch
that appended its content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical fixes:
- Convert hook from PostToolUse to PreToolUse so exit(2) blocking works
- Change all python references to python3 for cross-platform compat
- Add insaits-security-wrapper.js to bridge run-with-flags.js to Python
Standard fixes:
- Wrap hook with run-with-flags.js so users can disable via
ECC_DISABLED_HOOKS="pre:insaits-security"
- Add "async": true to hooks.json entry
- Add type annotations to all function signatures (Dict, List, Tuple, Any)
- Replace all print() statements with logging module (stderr)
- Fix silent OSError swallow in write_audit — now logs warning
- Remove os.environ.setdefault('INSAITS_DEV_MODE') — pass dev_mode=True
through monitor constructor instead
- Update hooks/README.md: moved to PreToolUse table, "detects" not
"catches", clarify blocking vs non-blocking behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add insaits-security-monitor.py: real-time AI security monitoring
hook that catches credential exposure, prompt injection,
hallucinations, and 20+ other anomaly types
- Update hooks.json with InsAIts PostToolUse entry
- Update hooks/README.md with InsAIts in PostToolUse table
- Add InsAIts MCP server entry to mcp-configs/mcp-servers.json
InsAIts (https://github.com/Nomadu27/InsAIts) is an open-source
runtime security layer for multi-agent AI. It runs 100% locally
and writes tamper-evident audit logs to .insaits_audit_session.jsonl.
Install: pip install insa-its
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>