{"version":3,"sources":["../../src/data/patterns.json","../../src/core/patterns-loader.ts","../../src/core/constants.ts","../../src/middleware/headers.ts","../../src/middleware/rate-limit.ts","../../src/middleware/error-handler.ts","../../src/core/errors.ts","../../src/middleware/telemetry.ts","../../src/data/bot-patterns.json","../../src/middleware/bot-detection.ts","../../src/middleware/sensitive-paths.ts","../../src/sanitizers/graphql.ts","../../src/sanitizers/mass-assignment.ts","../../src/validation/url.ts","../../src/sanitizers/prompt-injection.ts","../../src/sanitizers/utils.ts","../../src/sanitizers/xss.ts","../../src/sanitizers/sql.ts","../../src/sanitizers/path.ts","../../src/sanitizers/command.ts","../../src/sanitizers/ssti.ts","../../src/sanitizers/xxe.ts","../../src/sanitizers/ldap.ts","../../src/sanitizers/xpath.ts","../../src/sanitizers/headers.ts","../../src/sanitizers/deserialization.ts","../../src/sanitizers/nosql.ts","../../src/sanitizers/sanitize.ts","../../src/validation/schema.ts","../../src/validation/file.ts","../../src/logging/redactor.ts","../../src/telemetry/client.ts","../../src/utils/ip.ts","../../src/intelligence/client.ts","../../src/middleware/main.ts","../../src/middleware/nestjs.ts"],"names":["xff","result"],"mappings":"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","file":"index.mjs","sourcesContent":["{\n  \"version\": \"1.1.0\",\n  \"description\": \"Arcis Core Security Patterns - Language Agnostic\",\n  \"_pattern_convention\": {\n    \"description\": \"Pattern field naming convention for SDK implementers\",\n    \"pattern\": \"The primary regex pattern. May contain ReDoS-vulnerable constructs.\",\n    \"pattern_safe\": \"ReDoS-safe alternative pattern. SDKs MUST prefer this when available.\",\n    \"redos_safe\": \"Boolean indicating if 'pattern' is ReDoS-safe. If false, use 'pattern_safe'.\",\n    \"usage\": \"pattern_str = rule.get('pattern_safe') or rule.get('pattern')\"\n  },\n  \"config\": {\n    \"max_input_size\": 1000000,\n    \"max_recursion_depth\": 10,\n    \"enable_redos_protection\": true\n  },\n  \"patterns\": {\n    \"xss\": {\n      \"name\": \"Cross-Site Scripting (XSS)\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"xss-script-block\",\n          \"pattern\": \"<script[^>]*>[\\\\s\\\\S]*?</script>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects full script blocks (open tag through close tag)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-script-tag\",\n          \"pattern\": \"<script[^>]*>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects standalone or unclosed script tags\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-javascript-protocol\",\n          \"pattern\": \"javascript\\\\s*:[^\\\\s]\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects javascript: protocol (allows whitespace around colon)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-event-handler-quoted\",\n          \"pattern\": \"(?:[\\\\s/])on\\\\w+\\\\s*=\\\\s*[\\\"'][^\\\"']*[\\\"']\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects inline event handlers with quoted values (e.g. onclick=\\\"alert(1)\\\")\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-event-handler-unquoted\",\n          \"pattern\": \"(?:[\\\\s/])on\\\\w+\\\\s*=\\\\s*[^\\\\s>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects inline event handlers with unquoted values (e.g. onload=value)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-iframe-block\",\n          \"pattern\": \"<iframe[^>]*>[\\\\s\\\\S]*?</iframe>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects full iframe blocks\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-iframe\",\n          \"pattern\": \"<iframe[^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects iframe tags (partial or unclosed)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-style-block\",\n          \"pattern\": \"<style[^>]*>[\\\\s\\\\S]*?</style>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects full style blocks (CSS injection, expression(), behavior: attacks)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-style-tag\",\n          \"pattern\": \"<style[\\\\s>][^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects style tags (partial or unclosed). Requires whitespace or > after `style` so `<styled>` / `<StyledButton>` text is not flagged.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-object-block\",\n          \"pattern\": \"<object[^>]*>[\\\\s\\\\S]*?</object>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects full object blocks\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-object\",\n          \"pattern\": \"<object[^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects object tags (partial or unclosed)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-embed\",\n          \"pattern\": \"<embed[^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects embed tags\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-data-uri\",\n          \"pattern\": \"data\\\\s*:\\\\s*(?:text/html|image/svg)[^>\\\\s]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects data: URIs with HTML or SVG content (avoids 'metadata' false positives)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-vbscript\",\n          \"pattern\": \"vbscript\\\\s*:\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects vbscript: protocol\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-url-encoded\",\n          \"pattern\": \"%3Cscript\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects URL-encoded script tags\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-svg-onload\",\n          \"pattern\": \"<svg[^>]*onload[^>]*>\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects SVG with inline event handlers\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-form-injection\",\n          \"pattern\": \"<form[\\\\s>][^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects form tags used for phishing/credential harvesting via action= redirection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-meta-injection\",\n          \"pattern\": \"<meta[\\\\s>][^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects meta tags used for http-equiv refresh redirects or CSP bypass\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-base-injection\",\n          \"pattern\": \"<base[\\\\s>][^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects base href hijacking — redirects all relative URLs to attacker domain\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-link-injection\",\n          \"pattern\": \"<link[\\\\s>][^>]*\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects link tag injection used for stylesheet or preload CSRF attacks\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xss-css-expression\",\n          \"pattern\": \"expression\\\\s*\\\\(\",\n          \"flags\": \"gi\",\n          \"description\": \"Legacy IE CSS expression() in a style context, executes JS. Benchmark xss-style-expression.\",\n          \"redos_safe\": true\n        }\n      ],\n      \"encoding\": {\n        \"&\": \"&amp;\",\n        \"<\": \"&lt;\",\n        \">\": \"&gt;\",\n        \"\\\"\": \"&quot;\",\n        \"'\": \"&#x27;\"\n      }\n    },\n    \"sql_injection\": {\n      \"name\": \"SQL Injection\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"sqli-keywords\",\n          \"pattern\": \"(\\\\bUNION\\\\s+(?:ALL\\\\s+)?SELECT\\\\b)|(\\\\b(?:DROP|TRUNCATE)\\\\s+(?:TABLE|DATABASE|INDEX|VIEW|SCHEMA)\\\\b)|(\\\\bINTO\\\\s+(?:OUTFILE|DUMPFILE)\\\\b)|(\\\\bATTACH\\\\s+DATABASE\\\\b)|(\\\\bCREATE\\\\s+(?:USER|FUNCTION|TRIGGER|PROCEDURE)\\\\b)|(\\\\bGRANT\\\\s+(?:ALL|SELECT|INSERT|UPDATE|DELETE)\\\\b)|(\\\\bSHUTDOWN\\\\b)|(\\\\bxp_cmdshell\\\\b)|(\\\\bsp_executesql\\\\b)\",\n          \"flags\": \"gi\",\n          \"description\": \"Multi-token SQL attack shapes (UNION SELECT, DROP TABLE, INTO OUTFILE, etc.) that real attackers use and benign users essentially never type. Replaces older bare-keyword rule that false-positived on 'please select an option', 'I'll update you tomorrow'. Benchmark FP class B3, 2026-06-07.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"sqli-comments\",\n          \"pattern\": \"((?:^|[^!])--(?:[\\\\s-]|$)|/\\\\*|\\\\*/)\",\n          \"flags\": \"g\",\n          \"description\": \"SQL comments. ANSI -- requires a following space / dash / end-of-string so it matches a real trailing comment (1=1--, -- -) but not CLI flags (--max-retries). C-style /* */ kept. MySQL # excluded (see sqli-comment-quote). FPR pass 2026-06-08. The -- must not be immediately preceded by '!' so HTML comments (<!-- -->) are not flagged as SQL.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-boolean-numeric\",\n          \"pattern\": \"\\\\bOR\\\\s+\\\\d+\\\\s*=\\\\s*\\\\d+\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects OR 1=1 style injection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-boolean-string\",\n          \"pattern\": \"\\\\bOR\\\\s+['\\\"][^'\\\"]*['\\\"]\\\\s*=\\\\s*['\\\"][^'\\\"]*['\\\"]?\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects OR 'a'='a' style injection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-and-numeric\",\n          \"pattern\": \"\\\\bAND\\\\s+\\\\d+\\\\s*=\\\\s*\\\\d+\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects AND 1=1 style injection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-and-string\",\n          \"pattern\": \"\\\\bAND\\\\s+['\\\"][^'\\\"]*['\\\"]\\\\s*=\\\\s*['\\\"][^'\\\"]*['\\\"]?\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects AND 'a'='a' style injection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-sleep\",\n          \"pattern\": \"\\\\bSLEEP\\\\s*\\\\(\\\\s*\\\\d+\\\\s*\\\\)\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects time-based blind SQLi via SLEEP\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-benchmark\",\n          \"pattern\": \"\\\\bBENCHMARK\\\\s*\\\\(\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects time-based blind SQLi via BENCHMARK\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-pg-sleep\",\n          \"pattern\": \"\\\\bpg_sleep\\\\s*\\\\(\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects time-based blind SQLi via PostgreSQL pg_sleep\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-waitfor-delay\",\n          \"pattern\": \"\\\\bWAITFOR\\\\s+DELAY\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects time-based blind SQLi via MSSQL WAITFOR DELAY\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-oracle-dbms-packages\",\n          \"pattern\": \"\\\\bDBMS_(?:LOCK|PIPE|UTILITY|XSLPROCESSOR|JAVA|OUTPUT|SCHEDULER)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects Oracle DBMS_* package references used in time-based blind SQLi (DBMS_LOCK.SLEEP, DBMS_PIPE.RECEIVE_MESSAGE) and other Oracle stdlib abuse paths. Broad match — no legitimate user input contains these (improvements.md §1.1.e Q3).\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"sqli-hex-blob\",\n          \"pattern\": \"\\\\b0x[0-9a-fA-F]{16,}\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Long hex-encoded blob (8+ bytes) smuggling SQL past keyword filters; far longer than any hex color. Benchmark sql-hex-encoded.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"sqli-comment-quote\",\n          \"pattern\": \"'\\\\s*#\",\n          \"flags\": \"g\",\n          \"description\": \"Single-quote immediately followed by a MySQL # line comment (admin' #). Quote anchor avoids FP on bare # (hex colors, hashtags). Benchmark sql-comment-hash.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        }\n      ]\n    },\n    \"nosql_injection\": {\n      \"name\": \"NoSQL Injection\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"nosql-operators\",\n          \"pattern\": \"\\\\$(?:gt|gte|lt|lte|ne|eq|in|nin|and|or|not|nor|exists|type|regex|where|expr|mod|text|jsonSchema|function|accumulator|elemMatch|all|size|lookup|match|project|group|sort|limit|skip|unwind|addFields|replaceRoot)\\\\b\",\n          \"flags\": \"i\",\n          \"description\": \"Detects MongoDB operators\",\n          \"redos_safe\": true\n        }\n      ],\n      \"dangerous_keys\": [\n        \"$gt\",\n        \"$gte\",\n        \"$lt\",\n        \"$lte\",\n        \"$ne\",\n        \"$eq\",\n        \"$in\",\n        \"$nin\",\n        \"$and\",\n        \"$or\",\n        \"$not\",\n        \"$nor\",\n        \"$exists\",\n        \"$type\",\n        \"$regex\",\n        \"$where\",\n        \"$expr\",\n        \"$mod\",\n        \"$text\",\n        \"$jsonSchema\",\n        \"$function\",\n        \"$accumulator\",\n        \"$elemMatch\",\n        \"$all\",\n        \"$size\",\n        \"$lookup\",\n        \"$match\",\n        \"$project\",\n        \"$group\",\n        \"$sort\",\n        \"$limit\",\n        \"$skip\",\n        \"$unwind\",\n        \"$addFields\",\n        \"$replaceRoot\"\n      ]\n    },\n    \"command_injection\": {\n      \"name\": \"Command Injection\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"cmdi-shell-chars\",\n          \"pattern\": \"[;&|]\\\\s*(?:(?:cat|ls|dir|rm|cp|mv|wget|curl|nc|ncat|bash|sh|zsh|ksh|chmod|chown|kill|ps|id|touch|ping|dig|su|head|tail|php|sed|whoami|nslookup|nmap|python3?|perl|ruby|node|eval|exec|sudo|telnet|ssh|ftp|tftp|scp|awk|xxd)\\\\b|base64(?:\\\\s|$))\",\n          \"flags\": \"g\",\n          \"description\": \"Shell command chained after a metacharacter (; cat, | nc, & curl). Replaces the bare [;&|`] rule, which flagged every semicolon / ampersand in code, URLs and prose. FPR pass 2026-06-08. base64 requires a trailing space or end-of-input so `;base64 -d` is caught but the data-URI `;base64,` MIME parameter is not (FP on inline images).\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-command-substitution\",\n          \"pattern\": \"\\\\$\\\\(\",\n          \"flags\": \"g\",\n          \"description\": \"Detects command substitution syntax $( — paired form, fewer false positives than bare parens\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-ifs-bypass\",\n          \"pattern\": \"\\\\$\\\\{IFS(?:%[^}]*)?\\\\}\",\n          \"flags\": \"g\",\n          \"description\": \"Detects POSIX shell IFS substitution like ${IFS} or ${IFS%??}. Attackers use this to inject spaces past metacharacter filters in commands like `;cat${IFS}/etc/passwd` (improvements.md §1.1.e Q5).\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-control-chars\",\n          \"pattern\": \"%0[0-9a-fA-F]\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects URL-encoded control characters (%00-%0F) including null, tab, vertical tab, form feed, LF, CR\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-redirection\",\n          \"pattern\": \"(>>|<<<?)\",\n          \"flags\": \"g\",\n          \"description\": \"Append (>>) and here-doc (<<, <<<) redirection. The bare [<>] space form was dropped (matched 'a > b', 'RAM > 16GB'); redirect-to-file is covered by cmdi-redirect-syspath. FPR pass 2026-06-08.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-env-assign\",\n          \"pattern\": \"\\\\b(?:LD_PRELOAD|LD_LIBRARY_PATH|BASH_ENV|PYTHONPATH|PERL5LIB|DYLD_INSERT_LIBRARIES)\\\\s*=\",\n          \"flags\": \"gi\",\n          \"description\": \"Dangerous env-var assignment to smuggle code into a spawned process (LD_PRELOAD=). Benchmark cmd-env-var-smuggling.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-redirect-syspath\",\n          \"pattern\": \">\\\\s*/(?:etc|var|tmp|usr|bin|sbin|root|home|dev|proc|opt)\\\\b\",\n          \"flags\": \"g\",\n          \"description\": \"Shell output redirect to a system directory (> /var/www/shell.php). Anchored to system dirs to avoid math/text FP. Benchmark cmd-redirect-overwrite.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-newline-command\",\n          \"pattern\": \"[\\\\n\\\\r]\\\\s*(?:cat|ls|dir|rm|cp|mv|wget|curl|nc|ncat|bash|sh|zsh|ksh|chmod|chown|kill|ps|id|touch|ping|dig|su|head|tail|php|sed|whoami|nslookup|nmap|python3?|perl|ruby|node|eval|exec|sudo|telnet|ssh|ftp|tftp|scp|awk|xxd|base64)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Newline followed by a shell command (host\\\\ncat /etc/passwd). Benchmark cmd-newline-injection.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-backtick-command\",\n          \"pattern\": \"`\\\\s*(?:cat|ls|dir|rm|cp|mv|wget|curl|nc|ncat|bash|sh|zsh|ksh|chmod|chown|kill|ps|id|touch|ping|dig|su|head|tail|php|sed|whoami|nslookup|nmap|python3?|perl|ruby|node|eval|exec|sudo|telnet|ssh|ftp|tftp|scp|awk|xxd|base64)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Backtick command substitution wrapping a known command (`whoami`). Avoids FP on markdown inline code like `npm install`. FPR pass 2026-06-08.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-jndi-lookup\",\n          \"pattern\": \"\\\\$\\\\{jndi:\",\n          \"flags\": \"gi\",\n          \"description\": \"JNDI lookup used by Log4Shell, e.g. ${jndi:ldap://host/a}\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"cmdi-ssi-directive\",\n          \"pattern\": \"<!--\\\\s*#\\\\s*(?:exec|include|echo|config|fsize|flastmod|printenv)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Server-side include (SSI) directive, e.g. <!--#exec cmd=...-->\",\n          \"redos_safe\": true\n        }\n      ]\n    },\n    \"path_traversal\": {\n      \"name\": \"Path Traversal\",\n      \"severity\": \"high\",\n      \"owasp\": \"A01:2021\",\n      \"rules\": [\n        {\n          \"id\": \"path-dotdot\",\n          \"pattern\": \"\\\\.\\\\./\",\n          \"flags\": \"g\",\n          \"description\": \"Detects ../ sequences\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-dotdot-backslash\",\n          \"pattern\": \"\\\\.\\\\.\\\\\\\\\",\n          \"flags\": \"g\",\n          \"description\": \"Detects ..\\\\ sequences\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-encoded\",\n          \"pattern\": \"%2e%2e\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects URL-encoded traversal\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-double-encoded\",\n          \"pattern\": \"%252e\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects double URL-encoded traversal\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-double-encoded-slash\",\n          \"pattern\": \"%252f\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects double URL-encoded forward slash\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-dotdotslash-bypass\",\n          \"pattern\": \"\\\\.{2,}[/\\\\\\\\]{2,}\",\n          \"flags\": \"g\",\n          \"description\": \"Detects ....// and ....\\\\\\\\ bypass variants\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-null-byte\",\n          \"pattern\": \"%00\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects URL-encoded null byte injection\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-null-byte-literal\",\n          \"pattern\": \"\\\\x00\",\n          \"flags\": \"g\",\n          \"description\": \"Detects literal NUL byte in path inputs\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-mixed-encoded\",\n          \"pattern\": \"\\\\.\\\\.%2[fF]\",\n          \"flags\": \"g\",\n          \"description\": \"Detects mixed encoding: literal `..` followed by URL-encoded slash (%2F). Benchmark B6 — Python had no coverage; Node had this pattern. 2026-06-07.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-mixed-dot-encoded\",\n          \"pattern\": \"%2e\\\\.[\\\\\\\\/]\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects half-encoded traversal: URL-encoded dot (%2e) followed by a literal dot and a slash (`%2e./`). Node caught this; Python/Go did not. Migration 2026-06-13.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-mixed-dot-encoded-rev\",\n          \"pattern\": \"\\\\.%2e[\\\\\\\\/]\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects half-encoded traversal: literal dot followed by URL-encoded dot (%2e) and a slash (`.%2e/`). Node caught this; Python/Go did not. Migration 2026-06-13.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-overlong-utf8-dot\",\n          \"pattern\": \"%[Cc]0%[Aa][Ee]\",\n          \"flags\": \"g\",\n          \"description\": \"Detects overlong UTF-8 encoding of '.' (%C0%AE). Historic IIS/Apache decoder bypass. Real char `.` is %2E; overlong encoding only appears in evasion attempts. Benchmark B6 gap — neither SDK caught this before. 2026-06-07.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-overlong-utf8-slash\",\n          \"pattern\": \"%[Cc]0%[Aa][Ff]\",\n          \"flags\": \"g\",\n          \"description\": \"Detects overlong UTF-8 encoding of forward slash (%C0%AF). Same IIS/Apache decoder bypass class as path-overlong-utf8-dot. Real slash is %2F; overlong form only appears in evasion. 2026-06-13.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"path-windows-unc\",\n          \"pattern\": \"\\\\\\\\\\\\\\\\[A-Za-z0-9_.-]+\\\\\\\\\",\n          \"flags\": \"g\",\n          \"description\": \"Detects Windows UNC paths (\\\\\\\\\\\\\\\\server\\\\\\\\share) in user input. Legitimate web-app inputs never contain UNC references; attacker UNC payloads leak SMB auth or pull remote payloads. Benchmark B6. 2026-06-07.\",\n          \"redos_safe\": true\n        }\n      ]\n    },\n    \"prototype_pollution\": {\n      \"name\": \"Prototype Pollution\",\n      \"severity\": \"high\",\n      \"owasp\": \"A03:2021\",\n      \"languages\": [\n        \"javascript\",\n        \"typescript\"\n      ],\n      \"dangerous_keys\": [\n        \"__proto__\",\n        \"constructor\",\n        \"prototype\",\n        \"__definegetter__\",\n        \"__definesetter__\",\n        \"__lookupgetter__\",\n        \"__lookupsetter__\"\n      ]\n    },\n    \"ldap_injection\": {\n      \"name\": \"LDAP Injection\",\n      \"severity\": \"high\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"ldap-special\",\n          \"pattern\": \"[()\\\\\\\\*]\",\n          \"flags\": \"g\",\n          \"description\": \"Detects LDAP special characters. Broad rule for sanitization context only; NOT safe for request-boundary scanning (every parenthesised string trips it). Use 'ldap-injection-strict' below at request boundary.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ldap-injection-strict\",\n          \"pattern\": \"\\\\)\\\\s*\\\\(|\\\\*\\\\s*\\\\)\\\\s*\\\\(\",\n          \"flags\": \"g\",\n          \"description\": \"Detects attack-specific LDAP filter-break shapes ')(' and '*)('. Safe to wire into request-boundary scanners. Catches '*)(uid=*))(|(uid=*' style payloads.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"ldap-not-bypass\",\n          \"pattern\": \"\\\\)\\\\s*\\\\(\\\\s*!|&\\\\s*\\\\(\\\\s*!|\\\\|\\\\s*\\\\(\\\\s*!\",\n          \"flags\": \"g\",\n          \"description\": \"Detects LDAP NOT-operator bypass shapes ')(!', '&(!', and '|(!'. Catches injections where attacker appends a NOT clause to enumerate or exclude specific entries, e.g. '*)(uid=*)(!(uid=admin))'. Companion to ldap-injection-strict; together they cover the OR-then-NOT enumeration corpus that legitimate LDAP queries never produce. (improvements.md Q8.)\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"ldap-null-byte\",\n          \"pattern\": \"\\\\\\\\00|\\\\x00\",\n          \"flags\": \"g\",\n          \"description\": \"LDAP null-byte truncation (admin\\\\00) used to terminate a filter early and bypass appended constraints. Benchmark ldap-null-byte-truncate.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        }\n      ]\n    },\n    \"xpath_injection\": {\n      \"name\": \"XPath Injection\",\n      \"severity\": \"high\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"xpath-injection-strict\",\n          \"pattern\": \"('\\\\s*(or|and)\\\\s*'|\\\"\\\\s*(or|and)\\\\s*\\\"|\\\\)\\\\s*(or|and)\\\\s*\\\\(|\\\\|\\\\s*/)\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects XPath injection patterns: boolean-injection (' or ' / \\\" or \\\"), function-arity tampering with closing+opening parens around or/and, and union operator before path step. Request-boundary safe.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"xpath-blind-substring\",\n          \"pattern\": \"\\\\bsubstring\\\\s*\\\\(\\\\s*name\\\\s*\\\\(|\\\\bstring-length\\\\s*\\\\(|\\\\bcount\\\\s*\\\\(\\\\s*/\",\n          \"flags\": \"gi\",\n          \"description\": \"Blind XPath extraction via substring(name()), string-length(), count(/...). Benchmark xpath-blind-substring.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        }\n      ]\n    },\n    \"email_header_injection\": {\n      \"name\": \"Email Header Injection (SMTP CRLF)\",\n      \"severity\": \"high\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"email-header-smtp-keyword\",\n          \"pattern\": \"(\\\\r\\\\n|\\\\r|\\\\n)\\\\s*(bcc|cc|to|from|subject|reply-to|return-path|content-type|x-mailer)\\\\s*:\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects SMTP header injection: CR/LF followed by a known SMTP header keyword. Narrow enough for request-boundary scanning because legitimate user input rarely contains '\\\\nBcc:' verbatim.\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        },\n        {\n          \"id\": \"email-header-bare-newline\",\n          \"pattern\": \"(\\\\r\\\\n|\\\\r|\\\\n)\\\\s*[a-z][a-z0-9-]{0,40}\\\\s*:\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects bare CR/LF followed by ANY plausible header keyword (not just the SMTP allowlist). Catches MTAs that accept bare LF or bare CR as a header separator (qmail, sendmail variants), where attacker bypasses the strict keyword list by injecting a non-SMTP-keyword header (X-Custom, Authentication-Results, DKIM-Signature, ...). Companion to email-header-smtp-keyword; together they cover the bypass class. (improvements.md Q10.)\",\n          \"redos_safe\": true,\n          \"request_boundary_safe\": true\n        }\n      ]\n    },\n    \"ssti\": {\n      \"name\": \"Server-Side Template Injection (SSTI)\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"ssti-jinja2-twig\",\n          \"pattern\": \"\\\\{\\\\{.*?\\\\}\\\\}\",\n          \"flags\": \"g\",\n          \"description\": \"Detects Jinja2/Twig/Nunjucks template expressions ({{ ... }})\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-freemarker-spring\",\n          \"pattern\": \"\\\\$\\\\{.*?\\\\}\",\n          \"pattern_safe\": \"\\\\$\\\\{[^}]*[?!()*+\\\\-/][^}]*\\\\}\",\n          \"flags\": \"g\",\n          \"description\": \"Detects Freemarker/Thymeleaf/Spring EL expressions. Detection uses broad pattern; sanitization uses pattern_safe which requires operators/method-calls to avoid false-positives on JS template literals like ${name}.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-erb-ejs\",\n          \"pattern\": \"<%[=\\\\-]?.*?%>\",\n          \"flags\": \"gs\",\n          \"description\": \"Detects ERB/EJS template tags (<%= ... %>, <% ... %>)\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-pug-jade\",\n          \"pattern\": \"#\\\\{.*?\\\\}\",\n          \"pattern_safe\": \"#\\\\{[^}]*[?!()*+\\\\-/][^}]*\\\\}\",\n          \"flags\": \"g\",\n          \"description\": \"Detects Pug/Jade/Slim template expressions. Detection uses broad pattern; sanitization uses pattern_safe to avoid false-positives on Ruby/Pug output like #{name}.\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-python-class-chain\",\n          \"pattern\": \"__(?:class|mro|subclasses|globals|builtins|import)__\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects Python sandbox escape via dunder attributes\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-config-leak\",\n          \"pattern\": \"\\\\{\\\\{\\\\s*config[.\\\\[]\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects Jinja2 config/settings leak attempts\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-jinja2-functions\",\n          \"pattern\": \"\\\\{\\\\{\\\\s*(?:self|request|lipsum|cycler|joiner|namespace|range)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects Jinja2 built-in object/function access\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"ssti-velocity-ognl\",\n          \"pattern\": \"#set\\\\s*\\\\(\\\\s*\\\\$|#foreach\\\\s*\\\\(\\\\s*\\\\$|\\\\$\\\\w+\\\\.(?:exec|getClass|getRuntime|getMethod|invoke)\\\\b\",\n          \"flags\": \"gi\",\n          \"description\": \"Velocity #set/#foreach directives and OGNL/Velocity method calls. Benchmark ssti-velocity-runtime.\",\n          \"redos_safe\": true\n        }\n      ]\n    },\n    \"xml_injection\": {\n      \"name\": \"XML/XXE Injection\",\n      \"severity\": \"critical\",\n      \"owasp\": \"A03:2021\",\n      \"rules\": [\n        {\n          \"id\": \"xxe-doctype\",\n          \"pattern\": \"<!DOCTYPE\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects DOCTYPE declarations\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xxe-entity\",\n          \"pattern\": \"<!ENTITY\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects ENTITY declarations\",\n          \"redos_safe\": true\n        },\n        {\n          \"id\": \"xxe-system\",\n          \"pattern\": \"SYSTEM\\\\s+[\\\"']\",\n          \"flags\": \"gi\",\n          \"description\": \"Detects SYSTEM references\",\n          \"redos_safe\": true\n        }\n      ]\n    }\n  },\n  \"security_headers\": {\n    \"Content-Security-Policy\": \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; object-src 'none'; frame-ancestors 'none';\",\n    \"X-Content-Type-Options\": \"nosniff\",\n    \"X-Frame-Options\": \"DENY\",\n    \"X-XSS-Protection\": \"0\",\n    \"Strict-Transport-Security\": \"max-age=31536000; includeSubDomains\",\n    \"Referrer-Policy\": \"strict-origin-when-cross-origin\",\n    \"Permissions-Policy\": \"geolocation=(), microphone=(), camera=()\",\n    \"X-Permitted-Cross-Domain-Policies\": \"none\",\n    \"Cache-Control\": \"no-store, no-cache, must-revalidate, proxy-revalidate\",\n    \"Pragma\": \"no-cache\",\n    \"Expires\": \"0\"\n  },\n  \"rate_limiting\": {\n    \"default_max\": 100,\n    \"default_window_ms\": 60000,\n    \"headers\": {\n      \"limit\": \"X-RateLimit-Limit\",\n      \"remaining\": \"X-RateLimit-Remaining\",\n      \"reset\": \"X-RateLimit-Reset\"\n    }\n  },\n  \"sensitive_keys\": [\n    \"password\",\n    \"passwd\",\n    \"pwd\",\n    \"secret\",\n    \"token\",\n    \"apikey\",\n    \"api_key\",\n    \"apiKey\",\n    \"auth\",\n    \"authorization\",\n    \"credit_card\",\n    \"creditcard\",\n    \"cc\",\n    \"ssn\",\n    \"social_security\",\n    \"private_key\",\n    \"privateKey\",\n    \"access_token\",\n    \"accessToken\",\n    \"refresh_token\",\n    \"refreshToken\",\n    \"bearer\",\n    \"jwt\",\n    \"session\",\n    \"cookie\",\n    \"x-api-key\",\n    \"x-auth-token\",\n    \"credentials\"\n  ],\n  \"validation\": {\n    \"email\": \"^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$\",\n    \"url\": \"^https?://[^\\\\s/$.?#].[^\\\\s]*$\",\n    \"uuid\": \"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$\",\n    \"ipv4\": \"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\"\n  }\n}\n","/**\n * @module @arcis/node/core/patterns-loader\n *\n * Loads the shared security regex patterns from the bundled\n * `data/patterns.json` (a copy of the canonical `packages/core/patterns.json`,\n * kept byte-identical by the CI data-sync-check). This is the Node counterpart\n * of Go's `sanitizers/loader.go` and Python's `core/constants.load_patterns` +\n * `_compile_rules`.\n *\n * Why this exists: pre-migration, Node hardcoded every regex in `constants.ts`,\n * so each pattern edit was a manual dual-write against patterns.json (which\n * Python + Go already load at runtime). That is a Pattern 2 violation\n * (Shared Pattern Repository). Sourcing the arrays from patterns.json here\n * makes patterns.json the single source for all three SDKs.\n *\n * The JSON is a static `import`, so tsup inlines it into the CJS + ESM bundles\n * at build time (same as `bot-detection.ts` does with `bot-patterns.json`); no\n * runtime filesystem access. resolveJsonModule is already enabled in tsconfig.\n */\n\nimport patternsData from '../data/patterns.json';\n\ninterface PatternRule {\n  id: string;\n  pattern: string;\n  pattern_safe?: string;\n  flags?: string;\n}\n\ninterface PatternCategory {\n  rules?: PatternRule[];\n  dangerous_keys?: string[];\n}\n\ninterface PatternsSpec {\n  version: string;\n  patterns: Record<string, PatternCategory>;\n}\n\nconst spec = patternsData as unknown as PatternsSpec;\n\n/** Valid JavaScript RegExp flags. patterns.json uses g/i/m; anything else is dropped. */\nconst VALID_JS_FLAGS = new Set(['g', 'i', 'm', 's', 'u', 'y']);\n\nfunction normalizeFlags(flags: string | undefined): string {\n  if (!flags) return '';\n  let out = '';\n  for (const ch of flags) {\n    if (VALID_JS_FLAGS.has(ch) && !out.includes(ch)) out += ch;\n  }\n  return out;\n}\n\n/**\n * Compile every rule in a patterns.json category into a RegExp array, in file\n * order. Prefers the ReDoS-safe `pattern_safe` variant when present (parity\n * with Go's compileCategory / Python's _compile_rules). A category with no\n * rules returns an empty array.\n */\nexport function compileCategory(category: string): RegExp[] {\n  const cat = spec.patterns[category];\n  if (!cat?.rules) return [];\n  const out: RegExp[] = [];\n  for (const rule of cat.rules) {\n    const raw = rule.pattern_safe || rule.pattern;\n    if (!raw) continue;\n    out.push(new RegExp(raw, normalizeFlags(rule.flags)));\n  }\n  return out;\n}\n\n/**\n * Compile a single named rule from a category into one RegExp, or undefined if\n * the rule id is absent. Used where Node consumes a single pattern rather than\n * a list (e.g. the string-form NoSQL operator check).\n */\nexport function compileRule(category: string, id: string, flags?: string): RegExp | undefined {\n  const rule = spec.patterns[category]?.rules?.find((r) => r.id === id);\n  if (!rule) return undefined;\n  const raw = rule.pattern_safe || rule.pattern;\n  if (!raw) return undefined;\n  return new RegExp(raw, normalizeFlags(flags ?? rule.flags));\n}\n\n/**\n * Return the `dangerous_keys` list for a category (e.g. `nosql_injection`,\n * `prototype_pollution`), or an empty array if the category has none.\n */\nexport function dangerousKeysFor(category: string): string[] {\n  return spec.patterns[category]?.dangerous_keys ?? [];\n}\n\n/** The version string from the bundled patterns.json. Used by tests/diagnostics. */\nexport const PATTERNS_VERSION = spec.version;\n","/**\n * @module @arcis/node/core/constants\n * Named constants for Arcis - no magic numbers\n */\n\nimport { compileCategory, compileRule, dangerousKeysFor } from './patterns-loader';\n\n// =============================================================================\n// INPUT LIMITS\n// =============================================================================\nexport const INPUT = {\n  /** Default maximum input size (1MB) */\n  DEFAULT_MAX_SIZE: 1_000_000,\n  /** Maximum recursion depth for nested objects */\n  MAX_RECURSION_DEPTH: 10,\n} as const;\n\n// =============================================================================\n// RATE LIMITING\n// =============================================================================\nexport const RATE_LIMIT = {\n  /** Default window size (1 minute) */\n  DEFAULT_WINDOW_MS: 60_000,\n  /** Default max requests per window */\n  DEFAULT_MAX_REQUESTS: 100,\n  /** Default HTTP status code for rate limited responses */\n  DEFAULT_STATUS_CODE: 429,\n  /** Default error message */\n  DEFAULT_MESSAGE: 'Too many requests, please try again later.',\n  /** Minimum window size (1 second) */\n  MIN_WINDOW_MS: 1_000,\n  /** Maximum window size (24 hours) */\n  MAX_WINDOW_MS: 86_400_000,\n} as const;\n\n// =============================================================================\n// SECURITY HEADERS\n// =============================================================================\nexport const HEADERS = {\n  /** Default Content Security Policy */\n  DEFAULT_CSP: [\n    \"default-src 'self'\",\n    \"script-src 'self'\",\n    \"style-src 'self' 'unsafe-inline'\",\n    \"img-src 'self' data: https:\",\n    \"font-src 'self'\",\n    \"object-src 'none'\",\n    \"frame-ancestors 'none'\",\n  ].join('; '),\n  /** Default HSTS max age (1 year in seconds) */\n  HSTS_MAX_AGE: 31_536_000,\n  /** Default X-Frame-Options value */\n  FRAME_OPTIONS: 'DENY' as const,\n  /** Default X-Content-Type-Options value */\n  CONTENT_TYPE_OPTIONS: 'nosniff',\n  /** Default Referrer-Policy value */\n  REFERRER_POLICY: 'strict-origin-when-cross-origin',\n  /** Default Permissions-Policy value */\n  PERMISSIONS_POLICY: 'geolocation=(), microphone=(), camera=()',\n  /** Default Cache-Control value for security */\n  CACHE_CONTROL: 'no-store, no-cache, must-revalidate, proxy-revalidate',\n} as const;\n\n// =============================================================================\n// XSS PATTERNS (sourced from patterns.json)\n// =============================================================================\n\n/**\n * XSS patterns, compiled from the shared `patterns.json` `xss` category.\n *\n * Both detection (detectXss) and removal (sanitizeXss) iterate the same rule\n * list: the rules are precise capture patterns (full tag / attribute / protocol)\n * so they double as removal targets, and patterns.json file order keeps every\n * block rule (e.g. `<script>...</script>`) ahead of its bare-tag counterpart so\n * removal strips the larger match first. Pre-migration these were two hardcoded\n * arrays (a broad detect set + a precise remove set); single-sourcing them here\n * ends the dual-write against patterns.json and converges Node onto the same\n * detection Python + Go already ship (Pattern 2 + Pattern 7).\n */\nexport const XSS_PATTERNS = compileCategory('xss');\n\n/** Removal patterns for sanitizeXss(): the same patterns.json `xss` rules.\n *  A separate compiled array so its RegExp lastIndex state is independent of\n *  the detection pass. */\nexport const XSS_REMOVE_PATTERNS = compileCategory('xss');\n\n// =============================================================================\n// SQL INJECTION PATTERNS (sourced from patterns.json)\n// =============================================================================\n/** Compiled from the shared `patterns.json` `sql_injection` category. The\n *  quoted-boolean rules use RE2-safe `['\"]...['\"]` (no backreference) since\n *  patterns.json is also consumed by Go's RE2 engine; validated equivalent to\n *  the former backreference forms on the O'Brien / tautology corpus. */\nexport const SQL_PATTERNS = compileCategory('sql_injection');\n\n// =============================================================================\n// PATH TRAVERSAL PATTERNS (sourced from patterns.json)\n// =============================================================================\n/** Compiled from the shared `patterns.json` `path_traversal` category. */\nexport const PATH_PATTERNS = compileCategory('path_traversal');\n\n// =============================================================================\n// COMMAND INJECTION PATTERNS (sourced from patterns.json)\n// =============================================================================\n/** Compiled from the shared `patterns.json` `command_injection` category. */\nexport const COMMAND_PATTERNS = compileCategory('command_injection');\n\n// =============================================================================\n// DANGEROUS KEYS\n// =============================================================================\n\n/**\n * Prototype pollution keys to block.\n * Stored lowercase — always compare with key.toLowerCase().\n *\n * Includes:\n * - __proto__: direct prototype assignment\n * - constructor: access to constructor.prototype chain\n * - prototype: direct prototype property\n * - __defineGetter__/__defineSetter__: legacy property definition (can override getters/setters)\n * - __lookupGetter__/__lookupSetter__: legacy property introspection\n */\nexport const DANGEROUS_PROTO_KEYS = new Set(dangerousKeysFor('prototype_pollution'));\n\n/** MongoDB operators to block, from `patterns.json` nosql_injection.dangerous_keys. */\nexport const NOSQL_DANGEROUS_KEYS = new Set(dangerousKeysFor('nosql_injection'));\n\n/**\n * String-form NoSQL operator detection (block-mode scanThreats).\n *\n * NOSQL_DANGEROUS_KEYS catches operators that arrive as OBJECT KEYS\n * (`{\"$gt\": \"\"}`). But MongoDB operators also bypass as STRING VALUES —\n * query params like `?username[$ne]=1` arrive as the literal string\n * `$ne` before the body parser ever builds an object, and mongo-shell\n * payloads (`$where: '1==1'`) are plain strings. Node previously had no\n * string-level NoSQL check, so GoTestWAF scored NoSQL at 0% while Python\n * (which loads the shared `nosql-operators` rule) caught these. This\n * closes that Pattern-7 parity gap.\n *\n * Sourced from the `nosql-operators` rule in patterns.json. The trailing\n * `\\b` word boundary keeps `$invoice`/`$order`/`$index` from matching\n * `$in`/`$or` (a false-positive class the un-bounded rule had).\n */\nconst nosqlStringRule = compileRule('nosql_injection', 'nosql-operators');\nif (!nosqlStringRule) {\n  throw new Error('arcis: nosql-operators rule missing from patterns.json');\n}\nexport const NOSQL_STRING_PATTERN = nosqlStringRule;\n\n/**\n * Identity/auth field names that must hold a scalar value. A field here\n * carrying an array or object is a NoSQL type-juggling operator-injection\n * shape (e.g. {\"username\":[\"admin\"]}). v1.7 nosql-type-juggle.\n */\nexport const AUTH_FIELDS = new Set([\n  'username', 'user', 'userid', 'user_id', 'login', 'email',\n  'password', 'pass', 'passwd', 'pwd', 'token', 'apikey', 'api_key',\n  'secret', 'otp', 'pin',\n]);\n\n// =============================================================================\n// REDACTION\n// =============================================================================\nexport const REDACTION = {\n  /** Replacement text for redacted values */\n  REPLACEMENT: '[REDACTED]',\n  /** Truncation indicator */\n  TRUNCATED: '[TRUNCATED]',\n  /** Max depth indicator */\n  MAX_DEPTH: '[MAX_DEPTH]',\n  /** Default max message length */\n  DEFAULT_MAX_LENGTH: 10_000,\n  /** Default sensitive keys to redact */\n  SENSITIVE_KEYS: new Set([\n    'password', 'passwd', 'pwd', 'secret', 'token', 'apikey',\n    'api_key', 'apiKey', 'auth', 'authorization', 'credit_card',\n    'creditcard', 'cc', 'ssn', 'social_security', 'private_key',\n    'privateKey', 'access_token', 'accessToken', 'refresh_token',\n    'refreshToken', 'bearer', 'jwt', 'session', 'cookie',\n    'credentials', 'x-api-key', 'x-auth-token',\n  ]),\n} as const;\n\n// =============================================================================\n// VALIDATION PATTERNS\n// =============================================================================\nexport const VALIDATION = {\n  /**\n   * Email regex pattern.\n   * Rejects consecutive dots in local part (e.g. test..foo@example.com),\n   * leading/trailing dots, and other common invalid forms.\n   */\n  EMAIL: /^[^\\s@.][^\\s@]*(?:\\.[^\\s@.][^\\s@]*)*@[^\\s@]+\\.[^\\s@]+$/,\n  /**\n   * URL regex pattern.\n   * Only allows http:// and https:// (case-insensitive scheme per\n   * RFC 3986); explicitly rejects javascript:, data:, vbscript:, and\n   * other dangerous URI schemes.\n   */\n  URL: /^https?:\\/\\/[^\\s/$.?#][^\\s]*$/i,\n  /** UUID regex pattern (v4) */\n  UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n} as const;\n\n// =============================================================================\n// ERROR MESSAGES\n// =============================================================================\nexport const ERRORS = {\n  /** Generic error message (production) */\n  INTERNAL_SERVER_ERROR: 'Internal Server Error',\n  /** Input too large error */\n  INPUT_TOO_LARGE: (maxSize: number) => `Input exceeds maximum size of ${maxSize} bytes`,\n  /** Validation error messages */\n  VALIDATION: {\n    REQUIRED: (field: string) => `${field} is required`,\n    INVALID_TYPE: (field: string, type: string) => `${field} must be a ${type}`,\n    MIN_LENGTH: (field: string, min: number) => `${field} must be at least ${min} characters`,\n    MAX_LENGTH: (field: string, max: number) => `${field} must be at most ${max} characters`,\n    MIN_VALUE: (field: string, min: number) => `${field} must be at least ${min}`,\n    MAX_VALUE: (field: string, max: number) => `${field} must be at most ${max}`,\n    INVALID_FORMAT: (field: string) => `${field} format is invalid`,\n    INVALID_EMAIL: (field: string) => `${field} must be a valid email`,\n    INVALID_URL: (field: string) => `${field} must be a valid URL`,\n    INVALID_UUID: (field: string) => `${field} must be a valid UUID`,\n    INVALID_ENUM: (field: string, values: unknown[]) => `${field} must be one of: ${values.join(', ')}`,\n    MIN_ITEMS: (field: string, min: number) => `${field} must have at least ${min} items`,\n    MAX_ITEMS: (field: string, max: number) => `${field} must have at most ${max} items`,\n  },\n} as const;\n\n// =============================================================================\n// BLOCKED TEXT (for sanitizer replacements)\n// =============================================================================\nexport const BLOCKED = '[BLOCKED]' as const;\n","/**\n * @module @arcis/node/middleware/headers\n * Security headers middleware\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { HEADERS } from '../core/constants';\nimport type { HeaderOptions, HstsOptions } from '../core/types';\n\n/**\n * Create Express middleware for security headers.\n * Sets CSP, HSTS, X-Frame-Options, and other security headers.\n * \n * @param options - Header configuration\n * @returns Express middleware\n * \n * @example\n * app.use(createHeaders());\n * \n * @example\n * app.use(createHeaders({\n *   frameOptions: 'SAMEORIGIN',\n *   contentSecurityPolicy: \"default-src 'self'\"\n * }));\n */\nexport function createHeaders(options: HeaderOptions = {}): RequestHandler {\n  const {\n    contentSecurityPolicy = true,\n    xssFilter = true,\n    noSniff = true,\n    frameOptions = HEADERS.FRAME_OPTIONS,\n    hsts = true,\n    referrerPolicy = HEADERS.REFERRER_POLICY,\n    permissionsPolicy = HEADERS.PERMISSIONS_POLICY,\n    cacheControl = true,\n    crossOriginOpenerPolicy = 'same-origin',\n    crossOriginResourcePolicy = 'same-origin',\n    crossOriginEmbedderPolicy = 'require-corp',\n    originAgentCluster = true,\n    dnsPrefetchControl = true,\n  } = options;\n\n  return (req: Request, res: Response, next: NextFunction) => {\n    // Content Security Policy\n    if (contentSecurityPolicy) {\n      const csp = typeof contentSecurityPolicy === 'string' \n        ? contentSecurityPolicy \n        : HEADERS.DEFAULT_CSP;\n      res.setHeader('Content-Security-Policy', csp);\n    }\n\n    // X-XSS-Protection: 0 disables the legacy XSS auditor which was itself\n    // an attack vector (could be abused to selectively block legitimate scripts)\n    if (xssFilter) {\n      res.setHeader('X-XSS-Protection', '0');\n    }\n\n    // Prevent MIME type sniffing\n    if (noSniff) {\n      res.setHeader('X-Content-Type-Options', HEADERS.CONTENT_TYPE_OPTIONS);\n    }\n\n    // Clickjacking protection\n    if (frameOptions) {\n      res.setHeader('X-Frame-Options', frameOptions);\n    }\n\n    // HTTPS enforcement (HSTS)\n    // Only send HSTS over HTTPS — sending it over HTTP can brick HTTP-only\n    // development servers and confuses browsers that cache the directive.\n    // X-Forwarded-Proto is client-supplied so we validate the extracted value\n    // is exactly 'https' or 'http' before trusting it.\n    const forwardedProto = (req.headers['x-forwarded-proto'] as string | undefined)\n      ?.split(',')[0]\n      .trim()\n      .toLowerCase();\n    const trustedForwardedProto = forwardedProto === 'https' || forwardedProto === 'http'\n      ? forwardedProto\n      : undefined;\n    const isHttps = req.secure || trustedForwardedProto === 'https';\n\n    if (hsts && isHttps) {\n      const hstsOpts: HstsOptions = typeof hsts === 'object' ? hsts : {};\n      const maxAge = hstsOpts.maxAge ?? HEADERS.HSTS_MAX_AGE;\n      const includeSubDomains = hstsOpts.includeSubDomains !== false;\n      const preload = hstsOpts.preload === true;\n\n      let hstsValue = `max-age=${maxAge}`;\n      if (includeSubDomains) hstsValue += '; includeSubDomains';\n      if (preload) hstsValue += '; preload';\n\n      res.setHeader('Strict-Transport-Security', hstsValue);\n    }\n\n    // Referrer Policy\n    if (referrerPolicy) {\n      res.setHeader('Referrer-Policy', referrerPolicy);\n    }\n\n    // Permissions Policy\n    if (permissionsPolicy) {\n      res.setHeader('Permissions-Policy', permissionsPolicy);\n    }\n\n    // Cross-origin isolation headers (Spectre mitigation)\n    if (crossOriginOpenerPolicy) {\n      res.setHeader('Cross-Origin-Opener-Policy', crossOriginOpenerPolicy);\n    }\n\n    if (crossOriginResourcePolicy) {\n      res.setHeader('Cross-Origin-Resource-Policy', crossOriginResourcePolicy);\n    }\n\n    if (crossOriginEmbedderPolicy) {\n      res.setHeader('Cross-Origin-Embedder-Policy', crossOriginEmbedderPolicy);\n    }\n\n    // Request origin-keyed process isolation\n    if (originAgentCluster) {\n      res.setHeader('Origin-Agent-Cluster', '?1');\n    }\n\n    // Prevent DNS prefetching (privacy leak vector)\n    if (dnsPrefetchControl) {\n      res.setHeader('X-DNS-Prefetch-Control', 'off');\n    }\n\n    // Additional security headers\n    res.setHeader('X-Permitted-Cross-Domain-Policies', 'none');\n\n    // Cache-Control headers\n    if (cacheControl) {\n      const cacheControlValue = typeof cacheControl === 'string'\n        ? cacheControl\n        : HEADERS.CACHE_CONTROL;\n      res.setHeader('Cache-Control', cacheControlValue);\n      res.setHeader('Pragma', 'no-cache');\n      res.setHeader('Expires', '0');\n    }\n\n    // Remove fingerprinting headers\n    res.removeHeader('X-Powered-By');\n\n    next();\n  };\n}\n\n/**\n * Alias for createHeaders\n * @see createHeaders\n */\nexport const securityHeaders = createHeaders;\n","/**\n * @module @arcis/node/middleware/rate-limit\n * Rate limiting middleware\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { RATE_LIMIT } from '../core/constants';\nimport type { RateLimitOptions, RateLimiterMiddleware, RateLimitEntry } from '../core/types';\n\n/** In-memory rate limit store */\ninterface InMemoryRateLimitStore {\n  [key: string]: RateLimitEntry;\n}\n\n/**\n * Create Express middleware for rate limiting.\n * \n * @param options - Rate limit configuration\n * @returns Express middleware with cleanup method\n * \n * @example\n * app.use(createRateLimiter({ max: 100, windowMs: 60000 }));\n * \n * @example\n * // Skip rate limiting for certain routes\n * app.use(createRateLimiter({\n *   max: 50,\n *   skip: (req) => req.path === '/health'\n * }));\n * \n * @example\n * // Cleanup on shutdown\n * const limiter = createRateLimiter();\n * app.use(limiter);\n * process.on('SIGTERM', () => limiter.close());\n */\nexport function createRateLimiter(options: RateLimitOptions = {}): RateLimiterMiddleware {\n  const {\n    max = RATE_LIMIT.DEFAULT_MAX_REQUESTS,\n    windowMs = RATE_LIMIT.DEFAULT_WINDOW_MS,\n    message = RATE_LIMIT.DEFAULT_MESSAGE,\n    statusCode = RATE_LIMIT.DEFAULT_STATUS_CODE,\n    keyGenerator = (req) => {\n      const ip = req.ip ?? req.socket?.remoteAddress;\n      if (ip) return ip;\n      // SECURITY: When IP is unresolvable, fall back to a fingerprint of UA +\n      // Accept-Language so unresolvable clients don't share a single counter\n      // (one attacker could exhaust the limit and block every other client).\n      const ua = (req.headers['user-agent'] ?? '') as string;\n      const lang = (req.headers['accept-language'] ?? '') as string;\n      const fp = `${ua}|${lang}`;\n      // Small non-crypto hash — just needs to disperse unknown clients\n      let hash = 0;\n      for (let i = 0; i < fp.length; i++) hash = ((hash << 5) - hash + fp.charCodeAt(i)) | 0;\n      return `unknown:${hash.toString(36)}`;\n    },\n    skip,\n    store: externalStore,\n  } = options;\n\n  // Object.create(null) avoids prototype pollution if keyGenerator ever\n  // returns '__proto__', 'constructor', or 'prototype'.\n  const inMemoryStore = Object.create(null) as InMemoryRateLimitStore;\n\n  // Cleanup interval for in-memory store (only create if not using external store)\n  let cleanupInterval: ReturnType<typeof setInterval> | null = null;\n  \n  if (!externalStore) {\n    cleanupInterval = setInterval(() => {\n      const now = Date.now();\n      for (const key of Object.keys(inMemoryStore)) {\n        if (inMemoryStore[key].resetTime < now) {\n          delete inMemoryStore[key];\n        }\n      }\n    }, windowMs);\n\n    // Prevent interval from keeping the process alive (Node.js only)\n    if (typeof cleanupInterval.unref === 'function') {\n      cleanupInterval.unref();\n    }\n  }\n\n  const handler: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {\n    try {\n      if (skip?.(req)) {\n        return next();\n      }\n\n      const key = keyGenerator(req);\n      const now = Date.now();\n\n      let count: number;\n      let resetTime: number;\n\n      if (externalStore) {\n        // Use external store (e.g., Redis)\n        const entry = await externalStore.get(key);\n        if (!entry || entry.resetTime < now) {\n          await externalStore.set(key, { count: 1, resetTime: now + windowMs });\n          count = 1;\n          resetTime = now + windowMs;\n        } else {\n          count = await externalStore.increment(key);\n          resetTime = entry.resetTime;\n        }\n      } else {\n        // Use in-memory store\n        if (!inMemoryStore[key] || inMemoryStore[key].resetTime < now) {\n          inMemoryStore[key] = { count: 1, resetTime: now + windowMs };\n        } else {\n          inMemoryStore[key].count++;\n        }\n        count = inMemoryStore[key].count;\n        resetTime = inMemoryStore[key].resetTime;\n      }\n\n      const remaining = Math.max(0, max - count);\n      const resetSeconds = Math.ceil((resetTime - now) / 1000);\n\n      // Set rate limit headers\n      res.setHeader('X-RateLimit-Limit', max.toString());\n      res.setHeader('X-RateLimit-Remaining', remaining.toString());\n      res.setHeader('X-RateLimit-Reset', resetSeconds.toString());\n\n      if (count > max) {\n        res.setHeader('Retry-After', resetSeconds.toString());\n        res.status(statusCode).json({\n          error: message,\n          retryAfter: resetSeconds,\n        });\n        return;\n      }\n\n      next();\n    } catch (error) {\n      // External store failed — fall back to in-memory rate limiting.\n      // Pure fail-open is a security bypass; in-memory fallback maintains protection.\n      // eslint-disable-next-line no-console\n      console.error('[arcis] Rate limiter store error, using in-memory fallback:', error);\n      try {\n        const key = keyGenerator(req);\n        const now = Date.now();\n        if (!inMemoryStore[key] || inMemoryStore[key].resetTime < now) {\n          inMemoryStore[key] = { count: 1, resetTime: now + windowMs };\n        } else {\n          inMemoryStore[key].count++;\n        }\n        const count = inMemoryStore[key].count;\n        if (count > max) {\n          const resetSeconds = Math.ceil((inMemoryStore[key].resetTime - now) / 1000);\n          res.setHeader('Retry-After', resetSeconds.toString());\n          res.status(statusCode).json({ error: message, retryAfter: resetSeconds });\n          return;\n        }\n      } catch {\n        // If even fallback fails, allow through to preserve availability\n      }\n      next();\n    }\n  };\n\n  // Attach close method for cleanup\n  const middleware = handler as RateLimiterMiddleware;\n  middleware.close = () => {\n    if (cleanupInterval) {\n      clearInterval(cleanupInterval);\n      cleanupInterval = null;\n    }\n  };\n\n  return middleware;\n}\n\n/**\n * Alias for createRateLimiter\n * @see createRateLimiter\n */\nexport const rateLimit = createRateLimiter;\n","/**\n * @module @arcis/node/middleware/error-handler\n * Production-safe error handler middleware\n */\n\nimport type { Request, Response, NextFunction } from 'express';\nimport { ERRORS } from '../core/constants';\nimport type { ErrorHandlerOptions, HttpError } from '../core/types';\n\n/**\n * Patterns that indicate database or infrastructure internals in error messages.\n * When detected, the message is replaced with a generic error to prevent info leakage.\n */\nconst SENSITIVE_ERROR_PATTERNS: RegExp[] = [\n  // SQL database errors\n  /\\b(SQLITE_ERROR|SQLSTATE|ORA-\\d|PG::|mysql_|pg_query|ECONNREFUSED)/i,\n  /\\b(syntax error at or near|relation \".*\" does not exist)/i,\n  /\\b(column \".*\" (does not exist|of relation))/i,\n  /\\b(duplicate key value violates unique constraint)/i,\n  /\\b(table .* doesn't exist|unknown column)/i,\n  // MongoDB errors\n  /\\b(MongoError|MongoServerError|MongoNetworkError|E11000 duplicate key)/i,\n  // Redis errors\n  /\\b(WRONGTYPE|CROSSSLOT|CLUSTERDOWN|READONLY|ReplyError)/i,\n  // Connection strings and DSNs\n  /\\b(mongodb(\\+srv)?:\\/\\/|postgres(ql)?:\\/\\/|mysql:\\/\\/|redis:\\/\\/)/i,\n  // Stack traces with file paths\n  /\\bat\\s+.*\\.(js|ts|py|go|java):\\d+/i,\n  // Internal IP addresses\n  /\\b(127\\.0\\.0\\.\\d+|10\\.\\d+\\.\\d+\\.\\d+|192\\.168\\.\\d+\\.\\d+|172\\.(1[6-9]|2\\d|3[01])\\.\\d+\\.\\d+)\\b/,\n];\n\n/**\n * Check if an error message contains sensitive infrastructure details.\n */\nexport function containsSensitiveInfo(message: string): boolean {\n  return SENSITIVE_ERROR_PATTERNS.some(pattern => pattern.test(message));\n}\n\n/**\n * Create Express error handler that hides sensitive details in production.\n *\n * Prevents information leakage by:\n * - Hiding stack traces in production\n * - Hiding error messages unless explicitly exposed\n * - Scrubbing database errors, connection strings, and internal IPs\n *\n * @param options - Error handler configuration (or boolean for isDev)\n * @returns Express error handling middleware\n *\n * @example\n * // Production mode (default) - hides error details\n * app.use(errorHandler());\n *\n * @example\n * // Development mode - shows error details and stack traces\n * app.use(errorHandler({ isDev: true }));\n *\n * @example\n * // With custom logger\n * app.use(errorHandler({\n *   isDev: false,\n *   logger: arcis.logger()\n * }));\n */\nexport function errorHandler(\n  options: ErrorHandlerOptions | boolean = false\n): (err: Error, req: Request, res: Response, next: NextFunction) => void {\n  const isDev = typeof options === 'boolean' ? options : options.isDev ?? false;\n  const logErrors = typeof options === 'object' ? options.logErrors ?? true : true;\n  const logger = typeof options === 'object' ? options.logger : undefined;\n  const customHandler = typeof options === 'object' ? options.customHandler : undefined;\n\n  return (err: HttpError, req: Request, res: Response, _next: NextFunction) => {\n    // Clamp to a valid HTTP error range. A thrown error with a bogus\n    // statusCode (negative, zero, or > 599) would otherwise be sent to\n    // the client and break proxies, browsers, or compliance scanners.\n    const rawStatus = err.statusCode ?? err.status ?? 500;\n    const statusCode =\n      Number.isFinite(rawStatus) && rawStatus >= 400 && rawStatus <= 599\n        ? Math.floor(rawStatus)\n        : 500;\n\n    // Custom handler takes precedence\n    if (customHandler) {\n      return customHandler(err, req, res);\n    }\n\n    // Always log full error details server-side\n    if (logErrors) {\n      const logData = {\n        error: err.message,\n        stack: err.stack,\n        statusCode,\n        path: req.path,\n        method: req.method,\n      };\n\n      if (logger) {\n        logger.error('Request error', logData);\n      } else {\n        // eslint-disable-next-line no-console\n        console.error('[arcis] Request error:', logData);\n      }\n    }\n\n    // Build response\n    // Only expose err.message when err.expose === true (caller opted in) or in dev mode.\n    // This prevents internal details leaking through arbitrary 4xx errors that happen\n    // to contain sensitive info (e.g. \"DB query failed for user admin@corp.com\").\n    const exposeMessage = isDev || err.expose === true;\n\n    let clientMessage: string;\n    if (!exposeMessage) {\n      clientMessage = ERRORS.INTERNAL_SERVER_ERROR;\n    } else if (containsSensitiveInfo(err.message)) {\n      // Even when expose is true, scrub DB errors and infra details\n      clientMessage = isDev ? err.message : ERRORS.INTERNAL_SERVER_ERROR;\n    } else {\n      clientMessage = err.message;\n    }\n\n    const response: Record<string, unknown> = {\n      error: clientMessage,\n    };\n\n    // Only show details in development\n    if (isDev) {\n      response.stack = err.stack;\n      response.details = err.message;\n    }\n\n    res.status(statusCode).json(response);\n  };\n}\n\n/**\n * Alias for errorHandler\n * @see errorHandler\n */\nexport const createErrorHandler = errorHandler;\n","/**\n * @module @arcis/node/core/errors\n * Custom error classes for Arcis\n */\n\n/**\n * Base class for all Arcis errors\n */\nexport class ArcisError extends Error {\n  public readonly statusCode: number;\n  public readonly code: string;\n  /** Whether the error message is safe to expose to API clients. */\n  public readonly expose: boolean;\n\n  constructor(message: string, statusCode = 500, code = 'ARCIS_ERROR') {\n    super(message);\n    this.name = 'ArcisError';\n    this.statusCode = statusCode;\n    this.code = code;\n    // Client errors (4xx) have controlled messages — safe to expose.\n    // Server errors (5xx) may contain internal details — hide by default.\n    this.expose = statusCode < 500;\n\n    // Maintains proper stack trace for where error was thrown (V8 engines)\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n}\n\n/**\n * Error thrown when input validation fails\n */\nexport class ValidationError extends ArcisError {\n  public readonly errors: string[];\n\n  constructor(errors: string[]) {\n    super('Validation failed', 400, 'VALIDATION_ERROR');\n    this.name = 'ValidationError';\n    this.errors = errors;\n  }\n}\n\n/** Alias for ValidationError (backwards compatibility) */\nexport { ValidationError as ArcisValidationError };\n\n/**\n * Error thrown when rate limit is exceeded\n */\nexport class RateLimitError extends ArcisError {\n  public readonly retryAfter: number;\n\n  constructor(message: string, retryAfter: number) {\n    super(message, 429, 'RATE_LIMIT_EXCEEDED');\n    this.name = 'RateLimitError';\n    this.retryAfter = retryAfter;\n  }\n}\n\n/**\n * Error thrown when input is too large\n */\nexport class InputTooLargeError extends ArcisError {\n  public readonly maxSize: number;\n  public readonly actualSize: number;\n\n  constructor(maxSize: number, actualSize: number) {\n    super(`Input exceeds maximum size of ${maxSize} bytes`, 413, 'INPUT_TOO_LARGE');\n    this.name = 'InputTooLargeError';\n    this.maxSize = maxSize;\n    this.actualSize = actualSize;\n  }\n}\n\n/**\n * Error thrown when security threat is detected\n */\nexport class SecurityThreatError extends ArcisError {\n  public readonly threatType: string;\n  public readonly pattern: string;\n\n  constructor(threatType: string, pattern: string) {\n    super('Request blocked for security reasons', 400, 'SECURITY_THREAT');\n    this.name = 'SecurityThreatError';\n    this.threatType = threatType;\n    this.pattern = pattern;\n  }\n}\n\n/**\n * Error thrown when sanitization fails\n */\nexport class SanitizationError extends ArcisError {\n  constructor(message: string) {\n    super(message, 400, 'SANITIZATION_ERROR');\n    this.name = 'SanitizationError';\n  }\n}\n","/**\n * @module @arcis/node/middleware/telemetry\n * Bridges Arcis middleware decisions to a TelemetryClient.\n * Pattern 3 (two-layer): the client owns transport; this layer owns Express plumbing.\n */\n\nimport type { Request, RequestHandler } from 'express';\nimport type { TelemetryClient } from '../telemetry/client';\nimport type { TelemetryEvent, TelemetryDecision, TelemetrySeverity } from '../telemetry/types';\nimport { SecurityThreatError } from '../core/errors';\n\n/** Marker that inner middleware writes to and the emitter reads from. */\nexport interface ArcisTelemetryMarker {\n  vector?: string;\n  rule?: string;\n  severity?: TelemetrySeverity;\n  matchedPattern?: string;\n  reason?: string;\n  /** Pre-decided decision. If absent, the emitter infers from response status. */\n  decision?: TelemetryDecision;\n}\n\ndeclare module 'express-serve-static-core' {\n  interface Request {\n    /** Per-request marker populated by Arcis middlewares for telemetry attribution. */\n    __arcis?: ArcisTelemetryMarker;\n  }\n}\n\nconst THREAT_TO_VECTOR: Record<string, string> = {\n  xss: 'xss',\n  sql_injection: 'sql',\n  nosql_injection: 'nosql',\n  path_traversal: 'path',\n  command_injection: 'command',\n  prototype_pollution: 'prototype',\n  header_injection: 'header',\n  ssti: 'ssti',\n  xxe: 'xxe',\n};\n\n/**\n * Express middleware that records a telemetry event for every request.\n * Captures latency from entry, hooks `res.on('finish')`, and infers the\n * final decision from response status + any `req.__arcis` marker.\n */\nexport function createTelemetryEmitter(client: TelemetryClient): RequestHandler {\n  return (req, res, next) => {\n    const start = performance.now();\n\n    res.on('finish', () => {\n      try {\n        const event = buildEvent(req, res.statusCode, performance.now() - start);\n        client.record(event);\n      } catch {\n        // emit must never break the response — fail-open\n      }\n    });\n\n    next();\n  };\n}\n\n/**\n * Wraps the sanitizer middleware so SecurityThreatError → req.__arcis marker.\n * The emitter on `finish` will then have vector/rule/severity attribution.\n */\nexport function tapSanitizerThreats(handler: RequestHandler): RequestHandler {\n  return (req, res, next) => {\n    handler(req, res, (err?: unknown) => {\n      if (err instanceof SecurityThreatError) {\n        const vector = THREAT_TO_VECTOR[err.threatType] ?? err.threatType;\n        req.__arcis = {\n          vector,\n          rule: `${vector}/match`,\n          severity: 'high',\n          matchedPattern: err.pattern,\n          reason: err.message,\n          decision: 'deny',\n        };\n      }\n      next(err);\n    });\n  };\n}\n\nfunction buildEvent(req: Request, status: number, latencyMs: number): TelemetryEvent {\n  const marker = req.__arcis;\n  const decision = marker?.decision ?? inferDecision(status);\n\n  // Skip 5xx — those are server errors, not security decisions.\n  // Still emit so the dashboard shows traffic, but mark as allow with status >=500.\n  return {\n    ts: new Date().toISOString(),\n    ip: extractIp(req),\n    method: (req.method ?? 'GET').toUpperCase(),\n    path: req.path ?? req.url ?? '/',\n    decision,\n    vector: marker?.vector ?? (status === 429 ? 'rate-limit' : undefined),\n    rule: marker?.rule ?? (status === 429 ? 'rate-limit/exceeded' : undefined),\n    severity: marker?.severity ?? (status === 429 ? 'medium' : undefined),\n    userAgent: typeof req.headers?.['user-agent'] === 'string' ? req.headers['user-agent'] : '',\n    reason: marker?.reason,\n    status,\n    matchedPattern: marker?.matchedPattern,\n    latencyMs: Math.max(0, latencyMs),\n  };\n}\n\nfunction inferDecision(status: number): TelemetryDecision {\n  if (status === 429) return 'deny';\n  if (status === 400) return 'deny';\n  if (status === 403) return 'deny';\n  return 'allow';\n}\n\nfunction extractIp(req: Request): string {\n  if (typeof req.ip === 'string' && req.ip.length > 0) return req.ip;\n  const remote = req.socket?.remoteAddress;\n  return typeof remote === 'string' ? remote : '0.0.0.0';\n}\n","[\n  {\n    \"id\": \"ai-search-bot\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ai-search-bot\",\n    \"patterns\": [\n      \"AISearchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ai2-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ai2-crawler\",\n    \"patterns\": [\n      \"AI2Bot\\\\s\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ai2-crawler-dolma\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ai2-crawler-dolma\",\n    \"patterns\": [\n      \"Ai2Bot-Dolma\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"aihit-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"aihit-crawler\",\n    \"patterns\": [\n      \"aiHitBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"anthropic-ai-token\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"Anthropic\",\n    \"patterns\": [\n      \"anthropic-ai\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"anthropic-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ClaudeBot\",\n    \"patterns\": [\n      \"[cC]laude(?:[bB]ot|-[Ww]eb)\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"anthropic-crawler-search\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ClaudeSearchBot\",\n    \"patterns\": [\n      \"Claude-SearchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"anthropic-crawler-user\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ClaudeUser\",\n    \"patterns\": [\n      \"Claude-User\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"botify-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"botify-crawler\",\n    \"patterns\": [\n      \"botify\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bytedance-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"Bytespider\",\n    \"patterns\": [\n      \"Bytespider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ccbot-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"CCBot\",\n    \"patterns\": [\n      \"CCBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cohere-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"cohere-crawler\",\n    \"patterns\": [\n      \"cohere-ai\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"diffbot-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"diffbot-crawler\",\n    \"patterns\": [\n      \"Diffbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"friendlycrawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"friendlycrawler\",\n    \"patterns\": [\n      \"FriendlyCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"glutenfreepleasure-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"glutenfreepleasure-crawler\",\n    \"patterns\": [\n      \"Gluten Free Crawler\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"imagesift-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"imagesift-crawler\",\n    \"patterns\": [\n      \"ImagesiftBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"infegy-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"infegy-crawler\",\n    \"patterns\": [\n      \"collection@infegy\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"integralads-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"integralads-crawler\",\n    \"patterns\": [\n      \"IAS crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"leadcrunch-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"leadcrunch-crawler\",\n    \"patterns\": [\n      \"CrunchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mediatoolkit-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"mediatoolkit-crawler\",\n    \"patterns\": [\n      \"Mediatoolkitbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"meta-externalagent\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"Meta AI\",\n    \"patterns\": [\n      \"meta-externalagent\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ntent-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ntent-crawler\",\n    \"patterns\": [\n      \"NTENTbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"omgili-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"omgili-crawler\",\n    \"patterns\": [\n      \"omgili\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"openai-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"GPTBot\",\n    \"patterns\": [\n      \"GPTBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"openai-crawler-user\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"ChatGPTUser\",\n    \"patterns\": [\n      \"ChatGPT-User\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"perplexity-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"PerplexityBot\",\n    \"patterns\": [\n      \"PerplexityBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"perplexity-user\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"perplexity-user\",\n    \"patterns\": [\n      \"Perplexity-User\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"primal-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"primal-crawler\",\n    \"patterns\": [\n      \"Primalbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sbintuitions-bot\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"sbintuitions-bot\",\n    \"patterns\": [\n      \"SBIntuitionsBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"searchatlas-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"searchatlas-crawler\",\n    \"patterns\": [\n      \"SearchAtlas\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sentione-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"sentione-crawler\",\n    \"patterns\": [\n      \"SentiBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"storygize-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"storygize-crawler\",\n    \"patterns\": [\n      \"StorygizeBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"timpi-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"timpi-crawler\",\n    \"patterns\": [\n      \"Timpibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"velen-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"velen-crawler\",\n    \"patterns\": [\n      \"VelenPublicWebCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webzio-crawler-ai\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"webzio-crawler-ai\",\n    \"patterns\": [\n      \"webzio-extended\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"you-crawler\",\n    \"category\": \"AI_CRAWLER\",\n    \"name\": \"you-crawler\",\n    \"patterns\": [\n      \"YouBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cypress\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Cypress\",\n    \"patterns\": [\n      \"[Cc]ypress\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fake-msie6\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Fake IE6\",\n    \"patterns\": [\n      \"MSIE 6\\\\.0\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"headless-chrome\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Headless Chrome\",\n    \"patterns\": [\n      \"HeadlessChrome\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"javascript-phantom\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"PhantomJS\",\n    \"patterns\": [\n      \"PhantomJS\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"playwright\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Playwright\",\n    \"patterns\": [\n      \"[Pp]laywright\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"puppeteer\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Puppeteer\",\n    \"patterns\": [\n      \"[Pp]uppeteer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"selenium\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"Selenium\",\n    \"patterns\": [\n      \"[Ss]elenium\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webdriver\",\n    \"category\": \"AUTOMATED\",\n    \"name\": \"WebDriver\",\n    \"patterns\": [\n      \"[Ww]ebdriver\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"amazon-route53-health-check\",\n    \"category\": \"MONITORING\",\n    \"name\": \"amazon-route53-health-check\",\n    \"patterns\": [\n      \"Amazon Route 53 Health Check Service\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"azure-app-insights\",\n    \"category\": \"MONITORING\",\n    \"name\": \"azure-app-insights\",\n    \"patterns\": [\n      \"AppInsights\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"betterstack-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"betterstack-monitor\",\n    \"patterns\": [\n      \"Better Stack\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"betteruptime-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"betteruptime-monitor\",\n    \"patterns\": [\n      \"Better Uptime Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"brandverity-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"brandverity-crawler\",\n    \"patterns\": [\n      \"BrandVerity\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"censys-inspect\",\n    \"category\": \"MONITORING\",\n    \"name\": \"censys-inspect\",\n    \"patterns\": [\n      \"CensysInspect\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"changedetection-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"changedetection-crawler\",\n    \"patterns\": [\n      \"changedetection\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"checkly-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"checkly-monitor\",\n    \"patterns\": [\n      \"Checkly\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-healthchecks\",\n    \"category\": \"MONITORING\",\n    \"name\": \"cloudflare-healthchecks\",\n    \"patterns\": [\n      \"Cloudflare-Healthchecks\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-security-center\",\n    \"category\": \"MONITORING\",\n    \"name\": \"cloudflare-security-center\",\n    \"patterns\": [\n      \"https:\\\\/\\\\/developers\\\\.cloudflare\\\\.com\\\\/security-center\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-ssl-detector\",\n    \"category\": \"MONITORING\",\n    \"name\": \"cloudflare-ssl-detector\",\n    \"patterns\": [\n      \"Cloudflare-SSLDetector\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-traffic-manager\",\n    \"category\": \"MONITORING\",\n    \"name\": \"cloudflare-traffic-manager\",\n    \"patterns\": [\n      \"Cloudflare-Traffic-Manager\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"datadog-monitor-synthetics\",\n    \"category\": \"MONITORING\",\n    \"name\": \"Datadog\",\n    \"patterns\": [\n      \"Datadog\\\\/{0,1}Synthetics\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"deadlinkchecker\",\n    \"category\": \"MONITORING\",\n    \"name\": \"deadlinkchecker\",\n    \"patterns\": [\n      \"deadlinkchecker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"disqus-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"disqus-crawler\",\n    \"patterns\": [\n      \"Disqus\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dubbot-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"dubbot-crawler\",\n    \"patterns\": [\n      \"Dubbotbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dynatrace-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"dynatrace-monitor\",\n    \"patterns\": [\n      \"RuxitSynthetic\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"freewebmonitoring-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"freewebmonitoring-monitor\",\n    \"patterns\": [\n      \"FreeWebMonitoring SiteChecker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"freshworks-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"freshworks-monitor\",\n    \"patterns\": [\n      \"FreshpingBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-certificates-bridge\",\n    \"category\": \"MONITORING\",\n    \"name\": \"google-certificates-bridge\",\n    \"patterns\": [\n      \"Google-Certificates-Bridge\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-site-verification\",\n    \"category\": \"MONITORING\",\n    \"name\": \"google-site-verification\",\n    \"patterns\": [\n      \"Google-Site-Verification\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-structured-data-testing-tool\",\n    \"category\": \"MONITORING\",\n    \"name\": \"google-structured-data-testing-tool\",\n    \"patterns\": [\n      \"Google-Structured-Data-Testing-Tool\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hubspot-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"HubSpotBot\",\n    \"patterns\": [\n      \"HubSpot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hydrozen-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"hydrozen-monitor\",\n    \"patterns\": [\n      \"Hydrozen\\\\.io\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"kuma-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"kuma-monitor\",\n    \"patterns\": [\n      \"Uptime-Kuma\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"monitorbacklinks-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"monitorbacklinks-crawler\",\n    \"patterns\": [\n      \"MBCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"newrelic-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"newrelic-monitor\",\n    \"patterns\": [\n      \"NewRelicbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nixstats-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"nixstats-crawler\",\n    \"patterns\": [\n      \"NIXStatsbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"outbrain-link-checker\",\n    \"category\": \"MONITORING\",\n    \"name\": \"outbrain-link-checker\",\n    \"patterns\": [\n      \"outbrain\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pingdom-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"Pingdom\",\n    \"patterns\": [\n      \"[pP]ingdom\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"safedns-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"safedns-crawler\",\n    \"patterns\": [\n      \"SafeDNSBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sentry-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"sentry-crawler\",\n    \"patterns\": [\n      \"(^| )sentry\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sentry-uptime-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"sentry-uptime-monitor\",\n    \"patterns\": [\n      \"SentryUptimeBot\\\\/1\\\\.0\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"statuscake-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"statuscake-monitor\",\n    \"patterns\": [\n      \"StatusCake\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"surly-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"surly-crawler\",\n    \"patterns\": [\n      \"SurdotlyBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"testomato-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"testomato-crawler\",\n    \"patterns\": [\n      \"minicrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"uptime-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"uptime-monitor\",\n    \"patterns\": [\n      \"www\\\\.uptime\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"uptimebot-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"uptimebot-monitor\",\n    \"patterns\": [\n      \"Uptimebot\\\\.org\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"uptimerobot-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"UptimeRobot\",\n    \"patterns\": [\n      \"UptimeRobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-css\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-css\",\n    \"patterns\": [\n      \"W3C_CSS_Validator\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-feed\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-feed\",\n    \"patterns\": [\n      \"FeedValidator\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-html\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-html\",\n    \"patterns\": [\n      \"W3C_Validator\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-html-nu\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-html-nu\",\n    \"patterns\": [\n      \"Validator\\\\.nu\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-i18n\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-i18n\",\n    \"patterns\": [\n      \"W3C_I18n-Checker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-links\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-links\",\n    \"patterns\": [\n      \"W3C-checklink\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-mobile\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-mobile\",\n    \"patterns\": [\n      \"W3C-mobileOK\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"w3c-validator-unified\",\n    \"category\": \"MONITORING\",\n    \"name\": \"w3c-validator-unified\",\n    \"patterns\": [\n      \"W3C_Unicorn\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webpagetest-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"webpagetest-crawler\",\n    \"patterns\": [\n      \"(^| )PTST\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"xenu-crawler\",\n    \"category\": \"MONITORING\",\n    \"name\": \"xenu-crawler\",\n    \"patterns\": [\n      \"Xenu Link Sleuth\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"zabbix-monitor\",\n    \"category\": \"MONITORING\",\n    \"name\": \"zabbix-monitor\",\n    \"patterns\": [\n      \"Zabbix\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"academicbot-rtu\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"academicbot-rtu\",\n    \"patterns\": [\n      \"AcademicBotRTU\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"adagio-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"adagio-crawler\",\n    \"patterns\": [\n      \"Adagiobot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ahrefs-site-audit\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"ahrefs-site-audit\",\n    \"patterns\": [\n      \"AhrefsSiteAudit\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"blackboard-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"blackboard-crawler\",\n    \"patterns\": [\n      \"Blackboard\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cispa-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"cispa-crawler\",\n    \"patterns\": [\n      \"CISPA Webcrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-prefetch\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"cloudflare-prefetch\",\n    \"patterns\": [\n      \"CloudFlare-Prefetch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"coda-server-fetcher\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"coda-server-fetcher\",\n    \"patterns\": [\n      \"Coda-Server-Fetcher\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"conductor-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"conductor-crawler\",\n    \"patterns\": [\n      \"Caliperbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cookiehub-scan\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"cookiehub-scan\",\n    \"patterns\": [\n      \"CookieHubScan\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"curl\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"curl\",\n    \"patterns\": [\n      \"^curl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dareboost-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"dareboost-crawler\",\n    \"patterns\": [\n      \"DareBoost\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dcrawl\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"dcrawl\",\n    \"patterns\": [\n      \"dcrawl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domainsproject-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"domainsproject-crawler\",\n    \"patterns\": [\n      \"Domains Project\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"epfl-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"epfl-crawler\",\n    \"patterns\": [\n      \"A Patent Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gigablast-crawler-oss\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"gigablast-crawler-oss\",\n    \"patterns\": [\n      \"Gigablast\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"go-http\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Go-http-client\",\n    \"patterns\": [\n      \"Go-http-client\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"got\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"got\",\n    \"patterns\": [\n      \"sindresorhus\\\\/got\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gowiki-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"gowiki-crawler\",\n    \"patterns\": [\n      \"Gowikibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"http-get\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"http-get\",\n    \"patterns\": [\n      \"http_get\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"httpie\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"HTTPie\",\n    \"patterns\": [\n      \"^HTTPie\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"img2dataset\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"img2dataset\",\n    \"patterns\": [\n      \"img2dataset\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"insomnia\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Insomnia\",\n    \"patterns\": [\n      \"^[iI]nsomnia\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ipip-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"ipip-crawler\",\n    \"patterns\": [\n      \"HTTP Banner Detection\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-apache-httpclient\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Apache HttpClient\",\n    \"patterns\": [\n      \"^Apache-HttpClient\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-asynchttpclient\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-asynchttpclient\",\n    \"patterns\": [\n      \"AHC\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-crawler4j\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-crawler4j\",\n    \"patterns\": [\n      \"crawler4j\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-httpunit\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-httpunit\",\n    \"patterns\": [\n      \"httpunit\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-jersey\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-jersey\",\n    \"patterns\": [\n      \"HttpUrlConnection\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-jetty\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-jetty\",\n    \"patterns\": [\n      \"Jetty\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-okhttp\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"OkHttp\",\n    \"patterns\": [\n      \"okhttp\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-snacktory\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"java-snacktory\",\n    \"patterns\": [\n      \"Snacktory\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"java-stdlib\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Java HttpClient\",\n    \"patterns\": [\n      \"^Java\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"javascript-axios\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"axios\",\n    \"patterns\": [\n      \"axios\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"javascript-node-fetch\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"node-fetch\",\n    \"patterns\": [\n      \"node-fetch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"l9explore\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"l9explore\",\n    \"patterns\": [\n      \"l9explore\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"law-unimi-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"law-unimi-crawler\",\n    \"patterns\": [\n      \"BUbiNG\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"leipzig-findlinks\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"leipzig-findlinks\",\n    \"patterns\": [\n      \"findlink\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"leipzig-lcc\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"leipzig-lcc\",\n    \"patterns\": [\n      \"^LCC \"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"macocu-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"macocu-crawler\",\n    \"patterns\": [\n      \"MaCoCu\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"moat-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"moat-crawler\",\n    \"patterns\": [\n      \"moatbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"monsido-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"monsido-crawler\",\n    \"patterns\": [\n      \"Monsidobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"moz-site-audit\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"RogerBot\",\n    \"patterns\": [\n      \"rogerbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nagios-check-http\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"nagios-check-http\",\n    \"patterns\": [\n      \"check_http\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nict-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"nict-crawler\",\n    \"patterns\": [\n      \"ICC-Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nmap\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"nmap\",\n    \"patterns\": [\n      \"Nmap Scripting Engine\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nutch\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"nutch\",\n    \"patterns\": [\n      \"Nutch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"oncrawl\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"oncrawl\",\n    \"patterns\": [\n      \"OnCrawl\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"perl-libwww\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"libwww-perl\",\n    \"patterns\": [\n      \"libwww-perl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"perl-pcore\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"perl-pcore\",\n    \"patterns\": [\n      \"Pcore-HTTP\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"php-curlclass\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"php-curlclass\",\n    \"patterns\": [\n      \"^PHP-Curl-Class\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"php-phpcrawl\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"php-phpcrawl\",\n    \"patterns\": [\n      \"phpcrawl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"php-simple-scraper\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"php-simple-scraper\",\n    \"patterns\": [\n      \"SimpleScraper\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"php-simplepie\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"php-simplepie\",\n    \"patterns\": [\n      \"SimplePie\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"php-ua\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"PHP\",\n    \"patterns\": [\n      \"^PHP\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"postman\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Postman\",\n    \"patterns\": [\n      \"PostmanRuntime\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"postman-loose\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Postman\",\n    \"patterns\": [\n      \"^Postman[ /]\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-aiohttp\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-aiohttp\",\n    \"patterns\": [\n      \"aiohttp\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-bitbot\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-bitbot\",\n    \"patterns\": [\n      \"BitBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-httpx\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-httpx\",\n    \"patterns\": [\n      \"httpx\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-opengraph\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-opengraph\",\n    \"patterns\": [\n      \"python-opengraph\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-requests\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-requests\",\n    \"patterns\": [\n      \"python-requests\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-scrapy\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Scrapy\",\n    \"patterns\": [\n      \"Scrapy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"python-urllib\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"python-urllib\",\n    \"patterns\": [\n      \"Python-urllib\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"quantcast-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"quantcast-crawler\",\n    \"patterns\": [\n      \"Quantcastbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ruby\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"Ruby\",\n    \"patterns\": [\n      \"^Ruby\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ruby-metainspector\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"ruby-metainspector\",\n    \"patterns\": [\n      \"MetaInspector\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"screamingfrog-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"screamingfrog-crawler\",\n    \"patterns\": [\n      \"Screaming Frog SEO Spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"semanticscholar-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"SemanticScholarBot\",\n    \"patterns\": [\n      \"SemanticScholarBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sistrix-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"sistrix-crawler\",\n    \"patterns\": [\n      \"(sistrix|SISTRIX) [cC]rawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sitebulb\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"sitebulb\",\n    \"patterns\": [\n      \"sitebulb\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"stripe-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"stripe-crawler\",\n    \"patterns\": [\n      \"Stripebot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"summaly-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"summaly-crawler\",\n    \"patterns\": [\n      \"SummalyBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"turnitin-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"turnitin-crawler\",\n    \"patterns\": [\n      \"Turnitin\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"utexas-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"utexas-crawler\",\n    \"patterns\": [\n      \"UT-Dorkbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wget\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"wget\",\n    \"patterns\": [\n      \"[wW]get\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yamanalab-crawler\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"yamanalab-crawler\",\n    \"patterns\": [\n      \"Sonic\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yext-bot\",\n    \"category\": \"SCRAPER\",\n    \"name\": \"yext-bot\",\n    \"patterns\": [\n      \"YextBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"zgrab\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"zgrab\",\n    \"patterns\": [\n      \"zgrab\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"addsearch-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"addsearch-crawler\",\n    \"patterns\": [\n      \"AddSearchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ahrefs-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"AhrefsBot\",\n    \"patterns\": [\n      \"AhrefsBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"alexandria-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"alexandria-crawler\",\n    \"patterns\": [\n      \"AlexandriaOrgBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"algolia-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"algolia-crawler\",\n    \"patterns\": [\n      \"Algolia Crawler\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"amazon-adbot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"amazon-adbot\",\n    \"patterns\": [\n      \"AmazonAdBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"amazon-alexa-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"amazon-alexa-crawler\",\n    \"patterns\": [\n      \"exabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"amazon-cloudfront\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"amazon-cloudfront\",\n    \"patterns\": [\n      \"Amazon CloudFront\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"amazon-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"AmazonBot\",\n    \"patterns\": [\n      \"Amazonbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"apple-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Applebot\",\n    \"patterns\": [\n      \"Applebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"apple-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"apple-feedfetcher\",\n    \"patterns\": [\n      \"i[Tt][Mm][Ss]\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"archiveorg-archiver\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"ArchiveOrgBot\",\n    \"patterns\": [\n      \"archive\\\\.org_bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ask-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"ask-crawler\",\n    \"patterns\": [\n      \"Teoma\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"avira-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"avira-crawler\",\n    \"patterns\": [\n      \"SafeSearch microdata crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"awario-crawler-rss\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"awario-crawler-rss\",\n    \"patterns\": [\n      \"AwarioRssBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"baidu-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Baiduspider\",\n    \"patterns\": [\n      \"Baiduspider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bazqux-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"bazqux-feedfetcher\",\n    \"patterns\": [\n      \"BazQux\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bing-ads\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"bing-ads\",\n    \"patterns\": [\n      \"Adidxbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bing-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Bingbot\",\n    \"patterns\": [\n      \"bingbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bing-office-store\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"bing-office-store\",\n    \"patterns\": [\n      \"officestorebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"blogtraffic-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"blogtraffic-feedfetcher\",\n    \"patterns\": [\n      \"BlogTraffic\\\\/\\\\d\\\\.\\\\d+ Feed-Fetcher\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudflare-archiver\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"cloudflare-archiver\",\n    \"patterns\": [\n      \"CloudFlare-AlwaysOnline\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"commoncrawl-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"CommonCrawlBot\",\n    \"patterns\": [\n      \"CCBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"duckduckgo-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"DuckDuckBot\",\n    \"patterns\": [\n      \"DuckDuckBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"entireweb-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"entireweb-crawler\",\n    \"patterns\": [\n      \"speedy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ezid-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"ezid-crawler\",\n    \"patterns\": [\n      \"EZID\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"feedbin-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"feedbin-crawler\",\n    \"patterns\": [\n      \"Feedbin\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"feedly-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"feedly-feedfetcher\",\n    \"patterns\": [\n      \"Feedly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"feedspot-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"feedspot-feedfetcher\",\n    \"patterns\": [\n      \"Feedspot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"freshrss-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"freshrss-feedfetcher\",\n    \"patterns\": [\n      \"FreshRSS\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"g2reader-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"g2reader-crawler\",\n    \"patterns\": [\n      \"g2reader-bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"geedo-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"geedo-crawler\",\n    \"patterns\": [\n      \"GeedoBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"geedo-crawler-products\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"geedo-crawler-products\",\n    \"patterns\": [\n      \"GeedoProductSearch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-ads-conversions\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-ads-conversions\",\n    \"patterns\": [\n      \"Google-Ads-Conversions\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-adsbot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"AdsBotGoogle\",\n    \"patterns\": [\n      \"AdsBot-Google([^-]|$)\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-adsbot-mobile\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"GoogleAdsBot\",\n    \"patterns\": [\n      \"AdsBot-Google-Mobile\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-adsense\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"MediapartnersGoogle\",\n    \"patterns\": [\n      \"Mediapartners-Google\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-adsense-googlebot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-adsense-googlebot\",\n    \"patterns\": [\n      \"Mediapartners \\\\(Googlebot\\\\)\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-adwords\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-adwords\",\n    \"patterns\": [\n      \"Google-Adwords-Instant\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-appengine\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-appengine\",\n    \"patterns\": [\n      \"AppEngine-Google\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Googlebot\",\n    \"patterns\": [\n      \"Googlebot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-cloudvertex\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-crawler-cloudvertex\",\n    \"patterns\": [\n      \"Google-CloudVertexBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-image\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Googlebot-Image\",\n    \"patterns\": [\n      \"Googlebot-Image\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-mobile\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-crawler-mobile\",\n    \"patterns\": [\n      \"Googlebot-Mobile\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-news\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Googlebot-News\",\n    \"patterns\": [\n      \"Googlebot-News\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-other\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-crawler-other\",\n    \"patterns\": [\n      \"GoogleOther\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-safety\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-crawler-safety\",\n    \"patterns\": [\n      \"Google-Safety\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-store\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"StorebotGoogle\",\n    \"patterns\": [\n      \"Storebot-Google\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-crawler-video\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"Googlebot-Video\",\n    \"patterns\": [\n      \"Googlebot-Video\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-feedfetcher\",\n    \"patterns\": [\n      \"Feedfetcher-Google\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-inspection-tool\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-inspection-tool\",\n    \"patterns\": [\n      \"Google-InspectionTool\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-lighthouse\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-lighthouse\",\n    \"patterns\": [\n      \"Chrome-Lighthouse\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-physical-web\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-physical-web\",\n    \"patterns\": [\n      \"Google-PhysicalWeb\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-push-notifications\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"APIsGoogle\",\n    \"patterns\": [\n      \"APIs-Google\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-read-aloud\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-read-aloud\",\n    \"patterns\": [\n      \"Google-Read-Aloud\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-xrawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"google-xrawler\",\n    \"patterns\": [\n      \"google-xrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"iask-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"iask-crawler\",\n    \"patterns\": [\n      \"iaskspider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"inoreader-aggregator\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"inoreader-aggregator\",\n    \"patterns\": [\n      \"inoreader\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"internetarchive-crawler-oss\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"internetarchive-crawler-oss\",\n    \"patterns\": [\n      \"heritrix\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linguee-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"linguee-crawler\",\n    \"patterns\": [\n      \"Linguee Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"majestic-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"majestic-crawler\",\n    \"patterns\": [\n      \"MJ12bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"marginalia-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"marginalia-crawler\",\n    \"patterns\": [\n      \"search\\\\.marginalia\\\\.nu\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"meta-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"meta-crawler\",\n    \"patterns\": [\n      \"[Mm]eta-[Ee]xternal[Aa]gent\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"meta-externalads\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"meta-externalads\",\n    \"patterns\": [\n      \"meta-externalads\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"microsoft-research-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"microsoft-research-crawler\",\n    \"patterns\": [\n      \"msrbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"miniflux-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"miniflux-feedfetcher\",\n    \"patterns\": [\n      \"Miniflux\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mojeek-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"mojeek-crawler\",\n    \"patterns\": [\n      \"MojeekBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"msn-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"MsnBot\",\n    \"patterns\": [\n      \"msnbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"naver-crawler-rss\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"naver-crawler-rss\",\n    \"patterns\": [\n      \"NAVER Blog Rssbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"netestate-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"netestate-crawler\",\n    \"patterns\": [\n      \"netEstate NE Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"newsblur-aggregator\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"newsblur-aggregator\",\n    \"patterns\": [\n      \"NewsBlur\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nicecrawler-archive\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"nicecrawler-archive\",\n    \"patterns\": [\n      \"Nicecrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"openai-crawler-search\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"OAISearchBot\",\n    \"patterns\": [\n      \"OAI-SearchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"petalsearch-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"petalsearch-crawler\",\n    \"patterns\": [\n      \"PetalBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pipl-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"pipl-crawler\",\n    \"patterns\": [\n      \"PiplBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pocket-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"pocket-crawler\",\n    \"patterns\": [\n      \"PocketParser\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"qwant-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"qwant-crawler\",\n    \"patterns\": [\n      \"Qwantify\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"refind-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"refind-crawler\",\n    \"patterns\": [\n      \"Refindbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"rssbot-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"rssbot-feedfetcher\",\n    \"patterns\": [\n      \"rssbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"rssing-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"rssing-crawler\",\n    \"patterns\": [\n      \"RSSingBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"rssmicro-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"rssmicro-feedfetcher\",\n    \"patterns\": [\n      \"Atom Feed Robot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seekport-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"seekport-crawler\",\n    \"patterns\": [\n      \"Seekport\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"serendeputy-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"serendeputy-crawler\",\n    \"patterns\": [\n      \"SerendeputyBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"startme-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"startme-crawler\",\n    \"patterns\": [\n      \"startmebot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"stract-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"stract-crawler\",\n    \"patterns\": [\n      \"StractBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"superfeedr-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"superfeedr-crawler\",\n    \"patterns\": [\n      \"Superfeedr\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"theoldreader-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"theoldreader-crawler\",\n    \"patterns\": [\n      \"theoldreader\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ttrss-feedfetcher\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"ttrss-feedfetcher\",\n    \"patterns\": [\n      \"Tiny Tiny RSS\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webarchive-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"webarchive-crawler\",\n    \"patterns\": [\n      \"web-archive-net\\\\.com\\\\.bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webzio-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"webzio-crawler\",\n    \"patterns\": [\n      \"webzio\\\\s\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wellknown-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"wellknown-crawler\",\n    \"patterns\": [\n      \"WellKnownBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wordpress-crawler-rss\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"wordpress-crawler-rss\",\n    \"patterns\": [\n      \"feedbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yacy-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"yacy-crawler\",\n    \"patterns\": [\n      \"yacybot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yahoo-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"SlurpBot\",\n    \"patterns\": [\n      \"Slurp\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yahoo-crawler-japan\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"yahoo-crawler-japan\",\n    \"patterns\": [\n      \"Y!J\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yandex-crawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"YandexBot\",\n    \"patterns\": [\n      \"yandex\\\\.com\\\\/bots\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yandex-crawler-javascript\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"yandex-crawler-javascript\",\n    \"patterns\": [\n      \"YandexRenderResourcesBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yandex-loose\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"name\": \"YandexBot\",\n    \"patterns\": [\n      \"YandexBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"adyen-webhook\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"adyen-webhook\",\n    \"patterns\": [\n      \"Adyen HttpClient\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bing-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"BingPreviewBot\",\n    \"patterns\": [\n      \"BingPreview\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bitly-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"bitly-crawler\",\n    \"patterns\": [\n      \"bitlybot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"digg-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"digg-crawler\",\n    \"patterns\": [\n      \"Digg Deeper\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"discord-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"Discordbot\",\n    \"patterns\": [\n      \"Discordbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"duckduckgo-crawler-favicons\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"duckduckgo-crawler-favicons\",\n    \"patterns\": [\n      \"DuckDuckGo-Favicons-Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"embedly-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"EmbedlyBot\",\n    \"patterns\": [\n      \"Embedly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"everyonesocial-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"everyonesocial-crawler\",\n    \"patterns\": [\n      \"EveryoneSocialBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"facebook-catalog\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"facebook-catalog\",\n    \"patterns\": [\n      \"facebookcatalog\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"facebook-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"FacebookBot\",\n    \"patterns\": [\n      \"Face(book){0,1}[Bb]ot\"\n    ],\n    \"forbidden\": [\n      \"facebookexternalhit\",\n      \"Twitterbot\"\n    ]\n  },\n  {\n    \"id\": \"facebook-share-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"Facebook\",\n    \"patterns\": [\n      \"facebookexternalhit\"\n    ],\n    \"forbidden\": [\n      \"Twitterbot\",\n      \"Facebot\"\n    ]\n  },\n  {\n    \"id\": \"flipboard-proxy\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"flipboard-proxy\",\n    \"patterns\": [\n      \"FlipboardProxy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-favicon\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"google-favicon\",\n    \"patterns\": [\n      \"Google Favicon\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"google-preview\",\n    \"patterns\": [\n      \"Google Web Preview\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"google-web-snippet\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"google-web-snippet\",\n    \"patterns\": [\n      \"developers\\\\.google\\\\.com\\\\/\\\\+\\\\/web\\\\/snippet\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"groupme-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"groupme-crawler\",\n    \"patterns\": [\n      \"GroupMeBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"iframely-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"iframely-preview\",\n    \"patterns\": [\n      \"Iframely\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"imessage-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"imessage-preview\",\n    \"patterns\": [\n      \"facebookexternalhit\",\n      \"Twitterbot\",\n      \"Facebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"irc-archivebot\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"ArchiveBot\",\n    \"patterns\": [\n      \"ArchiveBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"keybase-bot\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"keybase-bot\",\n    \"patterns\": [\n      \"KeybaseBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lemmy-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"lemmy-crawler\",\n    \"patterns\": [\n      \"Lemmy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkarchiver\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"linkarchiver\",\n    \"patterns\": [\n      \"LinkArchiver\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkedin-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"LinkedInBot\",\n    \"patterns\": [\n      \"LinkedInBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mastodon-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"MastodonBot\",\n    \"patterns\": [\n      \"Mastodon\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"meta-crawler-user\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"meta-crawler-user\",\n    \"patterns\": [\n      \"meta-externalfetcher\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"microsoft-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"microsoft-preview\",\n    \"patterns\": [\n      \"MicrosoftPreview\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"neticle-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"neticle-crawler\",\n    \"patterns\": [\n      \"Neticle Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pagepeeker-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"pagepeeker-crawler\",\n    \"patterns\": [\n      \"PagePeeker\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pinterest-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"pinterest-crawler\",\n    \"patterns\": [\n      \"Pinterest(bot)?\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pintrest-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"PinterestBot\",\n    \"patterns\": [\n      \"pinterest\\\\.com\\\\/bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"reddit-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"RedditBot\",\n    \"patterns\": [\n      \"redditbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"skype-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"skype-preview\",\n    \"patterns\": [\n      \"SkypeUriPreview\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"slack-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"Slackbot\",\n    \"patterns\": [\n      \"Slackbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"slack-image-proxy\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"slack-image-proxy\",\n    \"patterns\": [\n      \"Slack-ImgProxy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"snap-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"snap-preview\",\n    \"patterns\": [\n      \"Snap URL Preview Service\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"steam-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"ValveSteamBot\",\n    \"patterns\": [\n      \"Valve\\\\/Steam\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"stripe-webhook\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"stripe-webhook\",\n    \"patterns\": [\n      \"Stripe\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"synapse-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"synapse-crawler\",\n    \"patterns\": [\n      \"Synapse\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"telegram-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"TelegramBot\",\n    \"patterns\": [\n      \"TelegramBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tiktok-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"tiktok-crawler\",\n    \"patterns\": [\n      \"TikTokSpider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"trendsmap-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"trendsmap-crawler\",\n    \"patterns\": [\n      \"TrendsmapResolver\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tweetedtimes-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"tweetedtimes-crawler\",\n    \"patterns\": [\n      \"tweetedtimes\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twitter-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"Twitterbot\",\n    \"patterns\": [\n      \"Twitterbot\"\n    ],\n    \"forbidden\": [\n      \"facebookexternalhit\",\n      \"Facebot\"\n    ]\n  },\n  {\n    \"id\": \"vercel-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"vercel-crawler\",\n    \"patterns\": [\n      \"Vercelbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vercel-monitor-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"vercel-monitor-preview\",\n    \"patterns\": [\n      \"vercel-screenshot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"viber-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"ViberBot\",\n    \"patterns\": [\n      \"Viber\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"whatsapp-crawler\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"WhatsApp\",\n    \"patterns\": [\n      \"WhatsApp\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yahoo-preview\",\n    \"category\": \"SOCIAL\",\n    \"name\": \"yahoo-preview\",\n    \"patterns\": [\n      \"Yahoo Link Preview\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"a6corp-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"a6corp-crawler\",\n    \"patterns\": [\n      \"A6-Indexer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"aboundex-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"aboundex-crawler\",\n    \"patterns\": [\n      \"Aboundex\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"acapbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"acapbot\",\n    \"patterns\": [\n      \"acapbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"acoon-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"acoon-crawler\",\n    \"patterns\": [\n      \"acoonbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"adbeat-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"adbeat-crawler\",\n    \"patterns\": [\n      \"adbeat_bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"addthis-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"addthis-crawler\",\n    \"patterns\": [\n      \"AddThis\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"admantx-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"admantx-crawler\",\n    \"patterns\": [\n      \"ADmantX\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"adscanner-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"adscanner-crawler\",\n    \"patterns\": [\n      \"adscanner\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"adstxtcrawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"adstxtcrawler\",\n    \"patterns\": [\n      \"AdsTxtCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"advbot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"advbot-crawler\",\n    \"patterns\": [\n      \"AdvBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"alphaseobot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"alphaseobot-crawler\",\n    \"patterns\": [\n      \"AlphaBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"anderspink-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"anderspink-crawler\",\n    \"patterns\": [\n      \"AndersPinkBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"antibot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"antibot\",\n    \"patterns\": [\n      \"antibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"apercite-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"apercite-crawler\",\n    \"patterns\": [\n      \"Apercite\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ara-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ara-crawler\",\n    \"patterns\": [\n      \"arabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"araturka-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"araturka-crawler\",\n    \"patterns\": [\n      \"Bot\\\\.AraTurka\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"arocom-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"arocom-crawler\",\n    \"patterns\": [\n      \"drupact\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"aspiegel-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"aspiegel-crawler\",\n    \"patterns\": [\n      \"AspiegelBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"audisto-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"audisto-crawler\",\n    \"patterns\": [\n      \"Audisto Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"awario-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"awario-crawler\",\n    \"patterns\": [\n      \"AwarioBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"awario-crawler-smart\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"awario-crawler-smart\",\n    \"patterns\": [\n      \"AwarioSmartBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"awesomecrawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"awesomecrawler\",\n    \"patterns\": [\n      \"awesomecrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"b2bbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"b2bbot\",\n    \"patterns\": [\n      \"B2B Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"backlinktest-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"backlinktest-crawler\",\n    \"patterns\": [\n      \"backlinkcrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"baidu-cloud-watch\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"baidu-cloud-watch\",\n    \"patterns\": [\n      \"Baidu-YunGuanCe\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"betabot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"betabot\",\n    \"patterns\": [\n      \"betaBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bidswitch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bidswitch-crawler\",\n    \"patterns\": [\n      \"bidswitchbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bigdatacorp-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bigdatacorp-crawler\",\n    \"patterns\": [\n      \"BDCbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"biglotron\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"biglotron\",\n    \"patterns\": [\n      \"BIGLOTRON\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"binlar\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"binlar\",\n    \"patterns\": [\n      \"binlar\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bitsight-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bitsight-crawler\",\n    \"patterns\": [\n      \"BitSightBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"blogmura-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"blogmura-crawler\",\n    \"patterns\": [\n      \"blogmuraBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"blp-bbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"blp-bbot\",\n    \"patterns\": [\n      \"BLP_bbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bnf-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bnf-crawler\",\n    \"patterns\": [\n      \"bnf\\\\.fr_bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bombora-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bombora-crawler\",\n    \"patterns\": [\n      \"BomboraBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"boxcar-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"boxcar-crawler\",\n    \"patterns\": [\n      \"BoxcarBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"brainobot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"brainobot\",\n    \"patterns\": [\n      \"brainobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"brandonmedia-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"brandonmedia-crawler\",\n    \"patterns\": [\n      \"BrandONbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"brandwatch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"brandwatch-crawler\",\n    \"patterns\": [\n      \"magpie-crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"brightedge-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"brightedge-crawler\",\n    \"patterns\": [\n      \"BrightEdge Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"bublup-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"bublup-crawler\",\n    \"patterns\": [\n      \"BublupBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"builtwith-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"builtwith-crawler\",\n    \"patterns\": [\n      \"^BW\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"buzzstream-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"buzzstream-crawler\",\n    \"patterns\": [\n      \"buzzbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"capsulink-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"capsulink-crawler\",\n    \"patterns\": [\n      \"CapsuleChecker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"careerx-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"careerx-crawler\",\n    \"patterns\": [\n      \"careerbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"centurybot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"centurybot\",\n    \"patterns\": [\n      \"centurybot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"checkmarknetwork-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"checkmarknetwork-crawler\",\n    \"patterns\": [\n      \"CheckMarkNetwork\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"chlooe-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"chlooe-crawler\",\n    \"patterns\": [\n      \"bot-pge\\\\.chlooe\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cincrawdata-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cincrawdata-crawler\",\n    \"patterns\": [\n      \"Cincraw\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"citeseerx-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"citeseerx-crawler\",\n    \"patterns\": [\n      \"citeseerxbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"clickagy-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"clickagy-crawler\",\n    \"patterns\": [\n      \"Clickagy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cliqz-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cliqz-crawler\",\n    \"patterns\": [\n      \"Cliqzbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cloudsystemnetworks-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cloudsystemnetworks-crawler\",\n    \"patterns\": [\n      \"Nimbostratus-Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"coccoc-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"coccoc-crawler\",\n    \"patterns\": [\n      \"coccoc\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cocolyze-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cocolyze-crawler\",\n    \"patterns\": [\n      \"Cocolyzebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"codewise-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"codewise-crawler\",\n    \"patterns\": [\n      \"VoluumDSP-content-bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cognitiveseo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cognitiveseo-crawler\",\n    \"patterns\": [\n      \"James BOT\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"companybook-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"companybook-crawler\",\n    \"patterns\": [\n      \"Companybook-Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"content-crawler-spider\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"content-crawler-spider\",\n    \"patterns\": [\n      \"content crawler spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"contextad-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"contextad-crawler\",\n    \"patterns\": [\n      \"ContextAd Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"contxbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"contxbot\",\n    \"patterns\": [\n      \"contxbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"convera-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"convera-crawler\",\n    \"patterns\": [\n      \"convera\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cookiebot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cookiebot-crawler\",\n    \"patterns\": [\n      \"Cookiebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"creativecommons-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"creativecommons-crawler\",\n    \"patterns\": [\n      \"CC Metadata Scaper\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"criteo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"criteo-crawler\",\n    \"patterns\": [\n      \"CriteoBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"crystalsemantics-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"crystalsemantics-crawler\",\n    \"patterns\": [\n      \"CrystalSemanticsBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"curebot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"curebot-crawler\",\n    \"patterns\": [\n      \"[Cc]urebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cutbot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cutbot-crawler\",\n    \"patterns\": [\n      \"Cutbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cxense-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cxense-crawler\",\n    \"patterns\": [\n      \"cXensebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"cyberpatrol-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"cyberpatrol-crawler\",\n    \"patterns\": [\n      \"CyberPatrol\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"datafeedwatch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"datafeedwatch-crawler\",\n    \"patterns\": [\n      \"Datafeedwatch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dataforseo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"dataforseo-crawler\",\n    \"patterns\": [\n      \"DataForSeoBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"datagnion-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"datagnion-crawler\",\n    \"patterns\": [\n      \"datagnionbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"datanyze-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"datanyze-crawler\",\n    \"patterns\": [\n      \"Datanyze\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dataprovider-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"dataprovider-crawler\",\n    \"patterns\": [\n      \"Dataprovider\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"datenbutler-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"datenbutler-crawler\",\n    \"patterns\": [\n      \"mindUpBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"daum-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"daum-crawler\",\n    \"patterns\": [\n      \"Daum\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"deepnoc-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"deepnoc-crawler\",\n    \"patterns\": [\n      \"deepnoc\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"deusu-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"deusu-crawler\",\n    \"patterns\": [\n      \"DeuSu\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"digincore-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"digincore-crawler\",\n    \"patterns\": [\n      \"Digincore bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"digitaldragon-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"digitaldragon-crawler\",\n    \"patterns\": [\n      \"CrawlyProjectCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"discoveryengine-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"discoveryengine-crawler\",\n    \"patterns\": [\n      \"discobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dnyz-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"dnyz-crawler\",\n    \"patterns\": [\n      \"DnyzBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domaincrawler-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"domaincrawler-crawler\",\n    \"patterns\": [\n      \"domaincrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domainreanimator-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"domainreanimator-crawler\",\n    \"patterns\": [\n      \"Domain Re-Animator Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domainsbot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"domainsbot-crawler\",\n    \"patterns\": [\n      \"Pandalytics\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domainstats-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"domainstats-crawler\",\n    \"patterns\": [\n      \"DomainStatsBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"domaintools-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"domaintools-crawler\",\n    \"patterns\": [\n      \"SurveyBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dotnetdotcom-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"dotnetdotcom-crawler\",\n    \"patterns\": [\n      \"ezooms\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"dragonmetrics-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"dragonmetrics-crawler\",\n    \"patterns\": [\n      \"Dragonbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"driftnet-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"driftnet-crawler\",\n    \"patterns\": [\n      \"InternetMeasurement\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"duedil-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"duedil-crawler\",\n    \"patterns\": [\n      \"electricmonk\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ec2linkfinder\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ec2linkfinder\",\n    \"patterns\": [\n      \"ec2linkfinder\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"edister-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"edister-crawler\",\n    \"patterns\": [\n      \"edisterbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"elisabot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"elisabot\",\n    \"patterns\": [\n      \"elisabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"epictions-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"epictions-crawler\",\n    \"patterns\": [\n      \"epicbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"eright-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"eright-crawler\",\n    \"patterns\": [\n      \"eright\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"europarchive-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"europarchive-crawler\",\n    \"patterns\": [\n      \"europarchive\\\\.org\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"eventures-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"eventures-crawler\",\n    \"patterns\": [\n      \"e\\\\.ventures Investment Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"eventures-crawler-batch\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"eventures-crawler-batch\",\n    \"patterns\": [\n      \"evc-batch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"exensa-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"exensa-crawler\",\n    \"patterns\": [\n      \"Bark[rR]owler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"experibot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"experibot-crawler\",\n    \"patterns\": [\n      \"Experibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"extlinks-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"extlinks-crawler\",\n    \"patterns\": [\n      \"ExtLinksBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"eyeota-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"eyeota-crawler\",\n    \"patterns\": [\n      \"Eyeotabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fast-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fast-crawler\",\n    \"patterns\": [\n      \"FAST-WebCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fast-crawler-enterprise\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fast-crawler-enterprise\",\n    \"patterns\": [\n      \"FAST Enterprise Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fedoraplanet-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fedoraplanet-crawler\",\n    \"patterns\": [\n      \"fedoraplanet\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"feedafever-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"feedafever-crawler\",\n    \"patterns\": [\n      \"Fever\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"femtosearch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"femtosearch-crawler\",\n    \"patterns\": [\n      \"FemtosearchBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"findthatfile-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"findthatfile-crawler\",\n    \"patterns\": [\n      \"findthatfile\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"flamingosearch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"flamingosearch-crawler\",\n    \"patterns\": [\n      \"Flamingo_SearchEngine\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fluffy\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fluffy\",\n    \"patterns\": [\n      \"fluffy\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fr-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fr-crawler\",\n    \"patterns\": [\n      \"fr-crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fuelbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fuelbot\",\n    \"patterns\": [\n      \"fuelbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"fyrebot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"fyrebot\",\n    \"patterns\": [\n      \"Fyrebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"g00g1e-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"g00g1e-crawler\",\n    \"patterns\": [\n      \"g00g1e\\\\.net\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"g2webservices-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"g2webservices-crawler\",\n    \"patterns\": [\n      \"G2 Web Services\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"garlik-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"garlik-crawler\",\n    \"patterns\": [\n      \"GarlikCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"genieo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"genieo-crawler\",\n    \"patterns\": [\n      \"Genieo\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gigablast-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"gigablast-crawler\",\n    \"patterns\": [\n      \"Gigabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ginger-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ginger-crawler\",\n    \"patterns\": [\n      \"GingerCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gnam-gnam-spider\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"gnam-gnam-spider\",\n    \"patterns\": [\n      \"gnam gnam spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gnowit-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"gnowit-crawler\",\n    \"patterns\": [\n      \"GnowitNewsbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"goo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"goo-crawler\",\n    \"patterns\": [\n      \"ichiro\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"grapeshot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"grapeshot-crawler\",\n    \"patterns\": [\n      \"GrapeshotCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"grob-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"grob-crawler\",\n    \"patterns\": [\n      \"Grobbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"grouphigh-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"grouphigh-crawler\",\n    \"patterns\": [\n      \"GroupHigh\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"grub\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"grub\",\n    \"patterns\": [\n      \"grub\\\\.org\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gslfbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"gslfbot\",\n    \"patterns\": [\n      \"gslfbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"gwene-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"gwene-crawler\",\n    \"patterns\": [\n      \"Gwene\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"haosou-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"haosou-crawler\",\n    \"patterns\": [\n      \"360Spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hatena-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"hatena-crawler\",\n    \"patterns\": [\n      \"Hatena\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"headline-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"headline-crawler\",\n    \"patterns\": [\n      \"ev-crawler\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hoyer-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"hoyer-crawler\",\n    \"patterns\": [\n      \"Friendica\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"httrack\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"httrack\",\n    \"patterns\": [\n      \"HTTrack\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hypefactors-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"hypefactors-crawler\",\n    \"patterns\": [\n      \"Buck\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hypestat-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"hypestat-crawler\",\n    \"patterns\": [\n      \"hypestat\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"hyscore-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"hyscore-crawler\",\n    \"patterns\": [\n      \"hyscore\\\\.io\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ia-archiver\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ia-archiver\",\n    \"patterns\": [\n      \"ia_archiver\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ideasandcode-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ideasandcode-crawler\",\n    \"patterns\": [\n      \"ICBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"indeed-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"indeed-crawler\",\n    \"patterns\": [\n      \"IndeedBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"inetdex-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"inetdex-crawler\",\n    \"patterns\": [\n      \"INETDEX-BOT\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"infoo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"infoo-crawler\",\n    \"patterns\": [\n      \"infoobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"integromedb-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"integromedb-crawler\",\n    \"patterns\": [\n      \"integromedb\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"intelium-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"intelium-crawler\",\n    \"patterns\": [\n      \"intelium_bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ionos-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ionos-crawler\",\n    \"patterns\": [\n      \"IonCrawl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ip-web-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ip-web-crawler\",\n    \"patterns\": [\n      \"ip-web-crawler\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"iskanie-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"iskanie-crawler\",\n    \"patterns\": [\n      \"iskanie\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"iss-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"iss-crawler\",\n    \"patterns\": [\n      \"filterdb\\\\.iss\\\\.net\\\\/crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"it2media-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"it2media-crawler\",\n    \"patterns\": [\n      \"it2media-domain-crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"itinfluentials-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"itinfluentials-crawler\",\n    \"patterns\": [\n      \"FindITAnswersbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jamiembrown-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jamiembrown-crawler\",\n    \"patterns\": [\n      \"Jamie's Spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jetslide-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jetslide-crawler\",\n    \"patterns\": [\n      \"Jetslide\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jobboerse-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jobboerse-crawler\",\n    \"patterns\": [\n      \"JobboerseBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jooble-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jooble-crawler\",\n    \"patterns\": [\n      \"Jooblebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jusprog-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jusprog-crawler\",\n    \"patterns\": [\n      \"Jugendschutzprogramm-Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"jyxo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"jyxo-crawler\",\n    \"patterns\": [\n      \"jyxobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"k7computing-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"k7computing-crawler\",\n    \"patterns\": [\n      \"K7MLWCBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"kemvi-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"kemvi-crawler\",\n    \"patterns\": [\n      \"Kemvibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"komodia-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"komodia-crawler\",\n    \"patterns\": [\n      \"KomodiaBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"kosmio-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"kosmio-crawler\",\n    \"patterns\": [\n      \"KosmioBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"landaumedia-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"landaumedia-crawler\",\n    \"patterns\": [\n      \"Landau-Media-Spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"laserlike-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"laserlike-crawler\",\n    \"patterns\": [\n      \"Laserlikebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lb-spider\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"lb-spider\",\n    \"patterns\": [\n      \"lb-spider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"leiki-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"leiki-crawler\",\n    \"patterns\": [\n      \"Leikibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lightspeedsystems-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"lightspeedsystems-crawler\",\n    \"patterns\": [\n      \"LightspeedSystemsCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"line-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"line-crawler\",\n    \"patterns\": [\n      \"Linespider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkapedia-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"linkapedia-crawler\",\n    \"patterns\": [\n      \"linkapediabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkdex-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"linkdex-crawler\",\n    \"patterns\": [\n      \"linkdex\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkfluence-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"linkfluence-crawler\",\n    \"patterns\": [\n      \"YaK\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"linkis-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"linkis-crawler\",\n    \"patterns\": [\n      \"LinkisBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lipperhey-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"lipperhey-crawler\",\n    \"patterns\": [\n      \"lipperhey\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"livelap-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"livelap-crawler\",\n    \"patterns\": [\n      \"Livelap[bB]ot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"logly-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"logly-crawler\",\n    \"patterns\": [\n      \"zenback bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"loop-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"loop-crawler\",\n    \"patterns\": [\n      \"netresearchserver\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lssbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"lssbot\",\n    \"patterns\": [\n      \"lssbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"lssbot-rocket\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"lssbot-rocket\",\n    \"patterns\": [\n      \"lssrocketcrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ltx71-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ltx71-crawler\",\n    \"patterns\": [\n      \"ltx71\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"luminator-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"luminator-crawler\",\n    \"patterns\": [\n      \"Luminator-robots\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mailru-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"MailRuBot\",\n    \"patterns\": [\n      \"Mail\\\\.RU_Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mappydata-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"mappydata-crawler\",\n    \"patterns\": [\n      \"mappydata\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mauibot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"mauibot\",\n    \"patterns\": [\n      \"MauiBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"megaindex-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"megaindex-crawler\",\n    \"patterns\": [\n      \"MegaIndex\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"meltwater-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"meltwater-crawler\",\n    \"patterns\": [\n      \"MeltwaterNews\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"metadatalabs-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"metadatalabs-crawler\",\n    \"patterns\": [\n      \"mlbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"metajob-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"metajob-crawler\",\n    \"patterns\": [\n      \"MetaJobBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"metauri-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"metauri-crawler\",\n    \"patterns\": [\n      \"MetaURI\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"metricstools-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"metricstools-crawler\",\n    \"patterns\": [\n      \"MTRobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mignify-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"mignify-crawler\",\n    \"patterns\": [\n      \"memorybot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mignify-imrbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"mignify-imrbot\",\n    \"patterns\": [\n      \"imrbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"mixnode-cache\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"mixnode-cache\",\n    \"patterns\": [\n      \"MixnodeCache\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"moodle-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"moodle-crawler\",\n    \"patterns\": [\n      \"MoodleBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"moreover-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"moreover-crawler\",\n    \"patterns\": [\n      \"Moreover\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"moz-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"moz-crawler\",\n    \"patterns\": [\n      \"dotbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"muckrack-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"muckrack-crawler\",\n    \"patterns\": [\n      \"MuckRack\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"multiviewbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"multiviewbot\",\n    \"patterns\": [\n      \"Multiviewbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"naver-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"naver-crawler\",\n    \"patterns\": [\n      \"Yeti\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"neeva-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"neeva-crawler\",\n    \"patterns\": [\n      \"Neevabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nerdbynature-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"nerdbynature-crawler\",\n    \"patterns\": [\n      \"NerdByNature\\\\.Bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nerdybot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"nerdybot-crawler\",\n    \"patterns\": [\n      \"nerdybot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"netcraft-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"netcraft-crawler\",\n    \"patterns\": [\n      \"NetcraftSurveyAgent\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"netsystemsresearch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"netsystemsresearch-crawler\",\n    \"patterns\": [\n      \"NetSystemsResearch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"netvibes-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"netvibes-crawler\",\n    \"patterns\": [\n      \"Netvibes\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"newsharecounts-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"newsharecounts-crawler\",\n    \"patterns\": [\n      \"newsharecounts\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"newspaper\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"newspaper\",\n    \"patterns\": [\n      \"newspaper\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nextcloud-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"NextCloudBot\",\n    \"patterns\": [\n      \"NextCloud\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"niki-bot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"niki-bot\",\n    \"patterns\": [\n      \"niki-bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ning-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ning-crawler\",\n    \"patterns\": [\n      \"NING\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ninjabot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ninjabot\",\n    \"patterns\": [\n      \"NINJA bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"nuzzel-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"nuzzel-crawler\",\n    \"patterns\": [\n      \"Nuzzel\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ocarinabot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ocarinabot\",\n    \"patterns\": [\n      \"Ocarinabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"okru-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"okru-crawler\",\n    \"patterns\": [\n      \"OdklBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"opengraphcheck-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"opengraphcheck-crawler\",\n    \"patterns\": [\n      \"OpenGraphCheck\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"openhose-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"openhose-crawler\",\n    \"patterns\": [\n      \"OpenHoseBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"openindex-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"openindex-crawler\",\n    \"patterns\": [\n      \"openindexspider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"orange-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"orange-crawler\",\n    \"patterns\": [\n      \"OrangeBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"orange-ftgroup-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"orange-ftgroup-crawler\",\n    \"patterns\": [\n      \"voilabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"outclicks-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"outclicks-crawler\",\n    \"patterns\": [\n      \"OutclicksBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"page-to-rss\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"page-to-rss\",\n    \"patterns\": [\n      \"page2rss\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pagething-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"pagething-crawler\",\n    \"patterns\": [\n      \"PageThing\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"paloaltonetworks-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"paloaltonetworks-crawler\",\n    \"patterns\": [\n      \"Expanse\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"panscient-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"panscient-crawler\",\n    \"patterns\": [\n      \"panscient\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"paperli-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"paperli-crawler\",\n    \"patterns\": [\n      \"PaperLiBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"phxbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"phxbot\",\n    \"patterns\": [\n      \"PhxBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"picsearch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"picsearch-crawler\",\n    \"patterns\": [\n      \"psbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"postrank-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"postrank-crawler\",\n    \"patterns\": [\n      \"postrank\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"prcy-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"prcy-crawler\",\n    \"patterns\": [\n      \"PR-CY\\\\.RU\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"privacore-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"privacore-crawler\",\n    \"patterns\": [\n      \"findxbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"privacyaware-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"privacyaware-crawler\",\n    \"patterns\": [\n      \"PrivacyAwareBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"profound-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"profound-crawler\",\n    \"patterns\": [\n      \"urlappendbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"proximic-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"proximic-crawler\",\n    \"patterns\": [\n      \"proximic\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pulsepoint-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"pulsepoint-crawler\",\n    \"patterns\": [\n      \"Pulsepoint\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"pure-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"pure-crawler\",\n    \"patterns\": [\n      \"purebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"rankactive-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"rankactive-crawler\",\n    \"patterns\": [\n      \"RankActiveLinkBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"retrevo-page-analyzer\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"retrevo-page-analyzer\",\n    \"patterns\": [\n      \"RetrevoPageAnalyzer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ridder-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ridder-crawler\",\n    \"patterns\": [\n      \"RidderBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"rivva-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"rivva-crawler\",\n    \"patterns\": [\n      \"Rivva\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ryte-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ryte-crawler\",\n    \"patterns\": [\n      \"RyteBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"scan-interfax-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"scan-interfax-crawler\",\n    \"patterns\": [\n      \"InterfaxScanBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"schmorp-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"schmorp-crawler\",\n    \"patterns\": [\n      \"AnyEvent\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"scoutjet-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"scoutjet-crawler\",\n    \"patterns\": [\n      \"ScoutJet\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"scribd-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"scribd-crawler\",\n    \"patterns\": [\n      \"scribdbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"scritch-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"scritch-crawler\",\n    \"patterns\": [\n      \"Fetch\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seekbot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seekbot-crawler\",\n    \"patterns\": [\n      \"seekbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seewithkids-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seewithkids-crawler\",\n    \"patterns\": [\n      \"seewithkids\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"semanticaudience-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"semanticaudience-crawler\",\n    \"patterns\": [\n      \"semanticbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sempitech-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sempitech-crawler\",\n    \"patterns\": [\n      \"sempi\\\\.tech\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"semrush-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"SemRushBot\",\n    \"patterns\": [\n      \"S[eE][mM]rushBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"senuto-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"senuto-crawler\",\n    \"patterns\": [\n      \"SenutoBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seobility-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seobility-crawler\",\n    \"patterns\": [\n      \"SeobilityBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seokicks-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seokicks-crawler\",\n    \"patterns\": [\n      \"SEOkicks\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seolizer-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seolizer-crawler\",\n    \"patterns\": [\n      \"SEOlizer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seoprofiler-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seoprofiler-crawler\",\n    \"patterns\": [\n      \"spbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seoscanners-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seoscanners-crawler\",\n    \"patterns\": [\n      \"seoscanners\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seostar-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seostar-crawler\",\n    \"patterns\": [\n      \"seostar\\\\.co\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seozoom-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ZoomBot\",\n    \"patterns\": [\n      \"ZoomBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"serpstatbot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"serpstatbot-crawler\",\n    \"patterns\": [\n      \"serpstatbot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"seznam-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"seznam-crawler\",\n    \"patterns\": [\n      \"SeznamBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"similartech-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"similartech-crawler\",\n    \"patterns\": [\n      \"smtbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"simple-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"simple-crawler\",\n    \"patterns\": [\n      \"SimpleCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sistrix-007ac9-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sistrix-007ac9-crawler\",\n    \"patterns\": [\n      \"007ac9 Crawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sitebot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sitebot-crawler\",\n    \"patterns\": [\n      \"sitebot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sitechecker-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sitechecker-crawler\",\n    \"patterns\": [\n      \"SiteCheckerBotCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"siteexplorer-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"siteexplorer-crawler\",\n    \"patterns\": [\n      \"siteexplorer\\\\.info\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"siteimprove-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"siteimprove-crawler\",\n    \"patterns\": [\n      \"Siteimprove\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"socialrank-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"socialrank-crawler\",\n    \"patterns\": [\n      \"SocialRankIOBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"softbytelabs-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"softbytelabs-crawler\",\n    \"patterns\": [\n      \"SBL-BOT\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sogou-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sogou-crawler\",\n    \"patterns\": [\n      \"Sogou\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"stuttgart-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"stuttgart-crawler\",\n    \"patterns\": [\n      \"RegionStuttgartBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"summify-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"summify-crawler\",\n    \"patterns\": [\n      \"summify\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"swimgbot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"swimgbot\",\n    \"patterns\": [\n      \"SWIMGBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"sysomos-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"sysomos-crawler\",\n    \"patterns\": [\n      \"Sysomos\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"t3versions-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"t3versions-crawler\",\n    \"patterns\": [\n      \"t3versionsBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"taboola-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"taboola-crawler\",\n    \"patterns\": [\n      \"Taboolabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tagoo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tagoo-crawler\",\n    \"patterns\": [\n      \"tagoobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tangiblee-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tangiblee-crawler\",\n    \"patterns\": [\n      \"TangibleeBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"thinklab-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"thinklab-crawler\",\n    \"patterns\": [\n      \"Thinklab\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tiger-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tiger-crawler\",\n    \"patterns\": [\n      \"tigerbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tineye-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tineye-crawler\",\n    \"patterns\": [\n      \"TinEye\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tiscali-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tiscali-crawler\",\n    \"patterns\": [\n      \"IstellaBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tombascraper-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tombascraper-crawler\",\n    \"patterns\": [\n      \"TombaPublicWebCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"toplist-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"toplist-crawler\",\n    \"patterns\": [\n      \"toplistbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"torus-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"torus-crawler\",\n    \"patterns\": [\n      \"ReverseEngineeringBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"toutiao-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"toutiao-crawler\",\n    \"patterns\": [\n      \"ToutiaoSpider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"traackr-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"traackr-crawler\",\n    \"patterns\": [\n      \"Traackr\\\\.com\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tracemyfile-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tracemyfile-crawler\",\n    \"patterns\": [\n      \"tracemyfile\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"trendiction-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"trendiction-crawler\",\n    \"patterns\": [\n      \"trendictionbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"trove-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"trove-crawler\",\n    \"patterns\": [\n      \"Trove\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"trovit-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"trovit-crawler\",\n    \"patterns\": [\n      \"trovitBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"tweetmemebot\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"tweetmemebot\",\n    \"patterns\": [\n      \"TweetmemeBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twenga-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"twenga-crawler\",\n    \"patterns\": [\n      \"twengabot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twingly-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"twingly-crawler\",\n    \"patterns\": [\n      \"Twingly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twoip-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"twoip-crawler\",\n    \"patterns\": [\n      \"2ip bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twoip-crawler-cms\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"twoip-crawler-cms\",\n    \"patterns\": [\n      \"2ip\\\\.ru\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"twurly-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"twurly-crawler\",\n    \"patterns\": [\n      \"Twurly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ubermetrics-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ubermetrics-crawler\",\n    \"patterns\": [\n      \"um-LN\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ubt-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ubt-crawler\",\n    \"patterns\": [\n      \"Streamline3Bot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"upflow-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"upflow-crawler\",\n    \"patterns\": [\n      \"Upflow\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"urlclassification-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"urlclassification-crawler\",\n    \"patterns\": [\n      \"KStandBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"usine-nouvelle-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"usine-nouvelle-crawler\",\n    \"patterns\": [\n      \"UsineNouvelleCrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"utorrent-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"utorrent-crawler\",\n    \"patterns\": [\n      \"BTWebClient\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vebidoo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vebidoo-crawler\",\n    \"patterns\": [\n      \"vebidoobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"veooz-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"veooz-crawler\",\n    \"patterns\": [\n      \"Veoozbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"verisign-ips-agent\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"verisign-ips-agent\",\n    \"patterns\": [\n      \"ips-agent\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vigil-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vigil-crawler\",\n    \"patterns\": [\n      \"Vigil\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vipnytt-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vipnytt-crawler\",\n    \"patterns\": [\n      \"jpg-newsbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"virustotal-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"virustotal-crawler\",\n    \"patterns\": [\n      \"virustotal\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vkrobot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vkrobot-crawler\",\n    \"patterns\": [\n      \"VKRobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vkshare-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vkshare-crawler\",\n    \"patterns\": [\n      \"vkShare\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"vuhuv-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"vuhuv-crawler\",\n    \"patterns\": [\n      \"vuhuvBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"warebay-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"warebay-crawler\",\n    \"patterns\": [\n      \"wbsearchbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webceo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webceo-crawler\",\n    \"patterns\": [\n      \"online-webceo-bot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webcompany-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webcompany-crawler\",\n    \"patterns\": [\n      \"webcompanycrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webdatastats-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webdatastats-crawler\",\n    \"patterns\": [\n      \"WebDataStats\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webeaver-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webeaver-crawler\",\n    \"patterns\": [\n      \"BehloolBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webmeup-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webmeup-crawler\",\n    \"patterns\": [\n      \"BLEXBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"webmon\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"webmon\",\n    \"patterns\": [\n      \"webmon \"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wesee-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"wesee-crawler\",\n    \"patterns\": [\n      \"WeSEE:Search\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wocodi-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"wocodi-crawler\",\n    \"patterns\": [\n      \"wocbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"woorank-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"woorank-crawler\",\n    \"patterns\": [\n      \"woobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"woorank-crawler-review\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"woorank-crawler-review\",\n    \"patterns\": [\n      \"woorankreview\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wordpress-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"WordPressBot\",\n    \"patterns\": [\n      \"WordPress\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wordup-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"wordup-crawler\",\n    \"patterns\": [\n      \"WordupInfoSearch\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"worio-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"worio-crawler\",\n    \"patterns\": [\n      \"woriobot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"wotbox-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"wotbox-crawler\",\n    \"patterns\": [\n      \"wotbox\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"xovibot-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"xovibot-crawler\",\n    \"patterns\": [\n      \"xovibot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yanga-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"yanga-crawler\",\n    \"patterns\": [\n      \"yanga\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yellowbp-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"yellowbp-crawler\",\n    \"patterns\": [\n      \"Yellowbrandprotectionbot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yisou-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"yisou-crawler\",\n    \"patterns\": [\n      \"YisouSpider\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"yooz-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"yooz-crawler\",\n    \"patterns\": [\n      \"yoozBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"zoominfo-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"zoominfo-crawler\",\n    \"patterns\": [\n      \"ZoominfoBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"zum-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"ZumBot\",\n    \"patterns\": [\n      \"ZumBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"zuperlist-crawler\",\n    \"category\": \"UNKNOWN\",\n    \"name\": \"zuperlist-crawler\",\n    \"patterns\": [\n      \"ZuperlistBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-ahrefsbotsiteaudit\",\n    \"name\": \"ahrefsbotsiteaudit\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"Ahrefs(Bot|SiteAudit)\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-amazonproductdiscovery\",\n    \"name\": \"amazonproductdiscovery\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"AmazonProductDiscovery\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-amazonsellerinitiatedlisting\",\n    \"name\": \"amazonsellerinitiatedlisting\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"AmazonSellerInitiatedListing\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-cclaudebbot\",\n    \"name\": \"cclaudebbot\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"[cC]laude[bB]ot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-meta-externalagent\",\n    \"name\": \"meta-externalagent\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"meta-externalagent\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-meta-externalfetcher\",\n    \"name\": \"meta-externalfetcher\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"meta-externalfetcher\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-hydrozenio\",\n    \"name\": \"hydrozenio\",\n    \"category\": \"MONITORING\",\n    \"patterns\": [\n      \"Hydrozen\\\\.io\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-yextbot\",\n    \"name\": \"yextbot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"YextBot\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-datadogsynthetics\",\n    \"name\": \"datadogsynthetics\",\n    \"category\": \"MONITORING\",\n    \"patterns\": [\n      \"DatadogSynthetics\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-observepoint\",\n    \"name\": \"observepoint\",\n    \"category\": \"MONITORING\",\n    \"patterns\": [\n      \"ObservePoint\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-checkly\",\n    \"name\": \"checkly\",\n    \"category\": \"MONITORING\",\n    \"patterns\": [\n      \"Checkly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-alittleclient\",\n    \"name\": \"alittleclient\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"ALittle Client\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-aliyunsecbot\",\n    \"name\": \"aliyunsecbot\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"AliyunSecBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-claude-web\",\n    \"name\": \"claude-web\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Claude-Web\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-google-extended\",\n    \"name\": \"google-extended\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Google-Extended\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-serankingbacklinksbot\",\n    \"name\": \"serankingbacklinksbot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"SERankingBacklinksBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-cmschecker\",\n    \"name\": \"cmschecker\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"CMSChecker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-wayback\",\n    \"name\": \"wayback\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Wayback\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-playwright\",\n    \"name\": \"playwright\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Playwright\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-puppeteer\",\n    \"name\": \"puppeteer\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Puppeteer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-selenium\",\n    \"name\": \"selenium\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"Selenium\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-nikto\",\n    \"name\": \"nikto\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"Nikto\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-sqlmap\",\n    \"name\": \"sqlmap\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"sqlmap\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-zmeu\",\n    \"name\": \"zmeu\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"ZmEu\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-masscan\",\n    \"name\": \"masscan\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"masscan\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-wpscan\",\n    \"name\": \"wpscan\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"WPScan\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-aacunetix\",\n    \"name\": \"aacunetix\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"[aA]cunetix\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-nessus\",\n    \"name\": \"nessus\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"Nessus\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-ddirbbuster\",\n    \"name\": \"ddirbbuster\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"[dD]ir[Bb]uster\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-colly\",\n    \"name\": \"colly\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"colly\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-mmechanize\",\n    \"name\": \"mmechanize\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"[mM]echanize\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-airaiscanning\",\n    \"name\": \"airaiscanning\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"air\\\\.ai\\\\/scanning\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-asnriskscorer\",\n    \"name\": \"asnriskscorer\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"asnriskscorer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-oicrawler\",\n    \"name\": \"oicrawler\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"OICrawler\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-l9scan\",\n    \"name\": \"l9scan\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"patterns\": [\n      \"l9scan\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-slaccalebot\",\n    \"name\": \"slaccalebot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"SlaccaleBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-customasynchttpclient\",\n    \"name\": \"customasynchttpclient\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"CustomAsyncHttpClient\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-gemini-deep-research\",\n    \"name\": \"gemini-deep-research\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"Gemini-Deep-Research\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-perplexity-user\",\n    \"name\": \"perplexity-user\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"Perplexity-User\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-perplexityuser\",\n    \"name\": \"perplexityuser\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"PerplexityUser\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-meta-webindexer\",\n    \"name\": \"meta-webindexer\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"meta-webindexer\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-duckassistbot\",\n    \"name\": \"duckassistbot\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"DuckAssistBot\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-mistralai-user\",\n    \"name\": \"mistralai-user\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"MistralAI-User\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-webzio\",\n    \"name\": \"webzio\",\n    \"category\": \"SEARCH_ENGINE\",\n    \"patterns\": [\n      \"webzio\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-newsai\",\n    \"name\": \"newsai\",\n    \"category\": \"SCRAPER\",\n    \"patterns\": [\n      \"newsai\\\\/\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"arcis-nuclei\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"nuclei\",\n    \"patterns\": [\n      \"Nuclei\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-openvas\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"openvas\",\n    \"patterns\": [\n      \"OpenVAS\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-ffuf\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"ffuf\",\n    \"patterns\": [\n      \"Fuzz Faster U Fool\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-nasl\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"nasl\",\n    \"patterns\": [\n      \".nasl\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-feroxbuster\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"feroxbuster\",\n    \"patterns\": [\n      \"feroxbuster\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-gobuster\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"gobuster\",\n    \"patterns\": [\n      \"gobuster\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-arachni\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"arachni\",\n    \"patterns\": [\n      \"Arachni\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-w3af\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"w3af\",\n    \"patterns\": [\n      \"w3af\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-skipfish\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"skipfish\",\n    \"patterns\": [\n      \"skipfish\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-netsparker\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"netsparker\",\n    \"patterns\": [\n      \"Netsparker\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-whatweb\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"whatweb\",\n    \"patterns\": [\n      \"WhatWeb\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-wfuzz\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"wfuzz\",\n    \"patterns\": [\n      \"Wfuzz\"\n    ],\n    \"forbidden\": []\n  },\n  {\n    \"id\": \"ext-qualys\",\n    \"category\": \"SECURITY_SCANNER\",\n    \"name\": \"qualys\",\n    \"patterns\": [\n      \"Qualys\"\n    ],\n    \"forbidden\": []\n  }\n]","/**\n * @module @arcis/node/middleware/bot-detection\n * Local-only bot detection using User-Agent and behavioral signals.\n *\n * Categorizes requests into bot types and allows/denies based on config.\n * No cloud calls — everything runs locally.\n *\n * @example\n * // Block automated tools, allow search engines\n * app.use(botProtection({\n *   allow: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'],\n *   deny: ['AUTOMATED', 'SCRAPER'],\n * }));\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport BOT_PATTERN_DATA from '../data/bot-patterns.json';\n\n// =============================================================================\n// BOT CATEGORIES\n// =============================================================================\n\nexport type BotCategory =\n  | 'SEARCH_ENGINE'\n  | 'SOCIAL'\n  | 'MONITORING'\n  | 'AI_CRAWLER'\n  | 'SCRAPER'\n  | 'SECURITY_SCANNER'\n  | 'AUTOMATED'\n  | 'UNKNOWN'\n  | 'HUMAN';\n\nexport interface BotDetectionResult {\n  /** Whether the request appears to be from a bot */\n  isBot: boolean;\n  /** Bot category */\n  category: BotCategory;\n  /** Matched bot name (e.g. 'Googlebot', 'curl') or null */\n  name: string | null;\n  /** Confidence score: 0-1 */\n  confidence: number;\n  /** Behavioral signals detected */\n  signals: string[];\n}\n\nexport interface BotProtectionOptions {\n  /** Categories to explicitly allow. Default: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'] */\n  allow?: BotCategory[];\n  /** Categories to explicitly deny. Default: ['AUTOMATED'] */\n  deny?: BotCategory[];\n  /** Action for categories not in allow or deny. Default: 'allow' */\n  defaultAction?: 'allow' | 'deny';\n  /** HTTP status code for denied bots. Default: 403 */\n  statusCode?: number;\n  /** Error message for denied bots */\n  message?: string;\n  /** Enable behavioral signal detection. Default: true */\n  detectBehavior?: boolean;\n  /** Custom handler called on detection (instead of default deny response) */\n  onDetected?: (req: Request, res: Response, result: BotDetectionResult) => void;\n}\n\n// =============================================================================\n// BOT DATABASE\n// =============================================================================\n\ninterface BotPattern {\n  /** Compiled regex(es) to match against the User-Agent. ANY match counts. */\n  patterns: RegExp[];\n  /** Compiled forbidden patterns. If ANY matches, this entry is rejected. */\n  forbidden: RegExp[];\n  /** Bot name (e.g. 'Googlebot') */\n  name: string;\n  /** Category */\n  category: BotCategory;\n  /** Stable identifier from the source corpus */\n  id: string;\n}\n\n/**\n * Source data for the bot corpus — `packages/core/bot-patterns.json`, derived\n * from arcjet/well-known-bots (MIT) plus a supplementary list of browser\n * automation tools the upstream doesn't separately track. Regenerate via\n * `python packages/core/generate-bot-patterns.py` after upgrading the source.\n */\ninterface BotPatternData {\n  id: string;\n  name: string;\n  category: string;\n  patterns: string[];\n  forbidden: string[];\n}\n\nfunction compilePattern(source: string): RegExp {\n  // Patterns from the corpus are JS-style regex bodies (no enclosing /.../ ).\n  // Compile case-insensitive: matches Arcis's documented contract that bot\n  // detection ignores UA case (`GPTBOT` and `gptbot` match the same entry).\n  // This is additive on top of Arcjet's explicit character classes like\n  // `[wW]get` — the `i` flag doesn't conflict with character ranges.\n  return new RegExp(source, 'i');\n}\n\nconst BOT_PATTERNS: BotPattern[] = (BOT_PATTERN_DATA as BotPatternData[]).map((entry) => ({\n  id: entry.id,\n  name: entry.name,\n  category: entry.category as BotCategory,\n  patterns: entry.patterns.map(compilePattern),\n  forbidden: entry.forbidden.map(compilePattern),\n}));\n\n// Snapshot of the bundled set, captured before any cloud merge, so tests can\n// restore a clean baseline.\nconst BUNDLED_PATTERNS: BotPattern[] = [...BOT_PATTERNS];\n\n/**\n * Merge cloud-fetched bot-corpus entries into the live pattern set (Phase C\n * cloud refresh). New ids are appended; existing ids are replaced in place so\n * a curated correction overrides the bundled entry. An entry with an\n * uncompilable pattern is skipped — this never throws into the refresh path\n * (fail-open). Process-global by design: the corpus is a singleton, same as the\n * bundled import. Returns the number of entries merged.\n */\nexport function mergeBotPatterns(entries: BotPatternData[]): number {\n  let merged = 0;\n  for (const entry of entries) {\n    try {\n      const compiled: BotPattern = {\n        id: entry.id,\n        name: entry.name,\n        category: entry.category as BotCategory,\n        patterns: entry.patterns.map(compilePattern),\n        forbidden: entry.forbidden.map(compilePattern),\n      };\n      const idx = BOT_PATTERNS.findIndex((b) => b.id === entry.id);\n      if (idx >= 0) BOT_PATTERNS[idx] = compiled;\n      else BOT_PATTERNS.push(compiled);\n      merged += 1;\n    } catch {\n      // skip an entry with a bad regex; never break the refresh\n    }\n  }\n  return merged;\n}\n\n/** Test hook — restore the bundled corpus, dropping any cloud-merged entries. */\nexport function _resetBotPatternsForTest(): void {\n  BOT_PATTERNS.length = 0;\n  BOT_PATTERNS.push(...BUNDLED_PATTERNS);\n}\n\n\n// =============================================================================\n// DETECTION ENGINE\n// =============================================================================\n\n/**\n * Detect behavioral signals that suggest a bot.\n */\nfunction detectBehavioralSignals(req: Request): string[] {\n  const signals: string[] = [];\n  const headers = req.headers;\n\n  // Missing User-Agent\n  if (!headers['user-agent']) {\n    signals.push('missing_user_agent');\n  }\n\n  // Missing Accept header (browsers always send this)\n  if (!headers['accept']) {\n    signals.push('missing_accept');\n  }\n\n  // Missing Accept-Language (browsers always send this)\n  if (!headers['accept-language']) {\n    signals.push('missing_accept_language');\n  }\n\n  // Missing Accept-Encoding (browsers always send this)\n  if (!headers['accept-encoding']) {\n    signals.push('missing_accept_encoding');\n  }\n\n  // Connection: close (browsers typically use keep-alive)\n  if (headers['connection'] === 'close') {\n    signals.push('connection_close');\n  }\n\n  return signals;\n}\n\n/**\n * Detect what kind of bot (if any) is making the request.\n *\n * @param req - HTTP request object\n * @returns Detection result with category, name, confidence, and signals\n *\n * @example\n * const result = detectBot(req);\n * if (result.isBot && result.category === 'AUTOMATED') {\n *   // Block automated tools\n * }\n */\nexport function detectBot(req: Request): BotDetectionResult {\n  const rawUa = req.headers['user-agent'] ?? '';\n  // SECURITY: A UA longer than 2048 chars is either buggy client or attempt to hide\n  // a bot signature past a truncation boundary. Flag as suspicious bot directly —\n  // don't silently truncate and continue.\n  if (rawUa.length > 2048) {\n    return {\n      isBot: true,\n      category: 'UNKNOWN',\n      name: null,\n      confidence: 0.9,\n      signals: detectBehavioralSignals(req),\n    };\n  }\n  const ua = rawUa;\n  const signals = detectBehavioralSignals(req);\n\n  // No User-Agent at all\n  if (!ua) {\n    return {\n      isBot: true,\n      category: 'UNKNOWN',\n      name: null,\n      confidence: 0.8,\n      signals,\n    };\n  }\n\n  // Match against known bot patterns. An entry matches when ALL of its\n  // accepted patterns match AND none of its forbidden patterns matches.\n  // ALL-of semantics makes multi-pattern entries (e.g. iMessage-Preview which\n  // expects both `facebookexternalhit` and `Twitterbot` in the same UA) only\n  // fire on real iMessage traffic, not on bare `Twitterbot/1.0` requests.\n  // Single-pattern entries (the common case) reduce trivially to that one\n  // pattern matching.\n  for (const bot of BOT_PATTERNS) {\n    let allMatched = bot.patterns.length > 0;\n    for (const pattern of bot.patterns) {\n      if (!pattern.test(ua)) {\n        allMatched = false;\n        break;\n      }\n    }\n    if (!allMatched) continue;\n\n    let forbidden = false;\n    for (const pattern of bot.forbidden) {\n      if (pattern.test(ua)) {\n        forbidden = true;\n        break;\n      }\n    }\n    if (forbidden) continue;\n\n    return {\n      isBot: true,\n      category: bot.category,\n      name: bot.name,\n      confidence: 0.95,\n      signals,\n    };\n  }\n\n  // Behavioral analysis for unrecognized UAs\n  const behaviorScore = signals.length;\n\n  // 3+ missing standard headers = likely bot\n  if (behaviorScore >= 3) {\n    return {\n      isBot: true,\n      category: 'UNKNOWN',\n      name: null,\n      confidence: Math.min(1.0, 0.6 + (behaviorScore * 0.1)),\n      signals,\n    };\n  }\n\n  return {\n    isBot: false,\n    category: 'HUMAN',\n    name: null,\n    confidence: Math.max(0.0, 1.0 - (behaviorScore * 0.15)),\n    signals,\n  };\n}\n\n/**\n * Create Express middleware for bot protection.\n *\n * @example\n * // Block automated tools and scrapers\n * app.use(botProtection({\n *   allow: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'],\n *   deny: ['AUTOMATED', 'SCRAPER'],\n * }));\n *\n * @example\n * // Block everything except search engines\n * app.use(botProtection({\n *   allow: ['SEARCH_ENGINE'],\n *   defaultAction: 'deny',\n * }));\n *\n * @example\n * // Custom handler\n * app.use(botProtection({\n *   deny: ['AUTOMATED'],\n *   onDetected: (req, res, result) => {\n *     console.log(`Bot blocked: ${result.name} (${result.category})`);\n *     res.status(403).json({ error: 'Bots not allowed' });\n *   },\n * }));\n */\nexport function botProtection(options: BotProtectionOptions = {}): RequestHandler {\n  const {\n    allow = ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'],\n    deny = ['AUTOMATED'],\n    defaultAction = 'allow',\n    statusCode = 403,\n    message = 'Access denied.',\n    onDetected,\n  } = options;\n\n  const allowSet = new Set(allow);\n  const denySet = new Set(deny);\n\n  return (req: Request, res: Response, next: NextFunction) => {\n    const result = detectBot(req);\n\n    // Attach result to request for downstream use\n    (req as unknown as Record<string, unknown>).botDetection = result;\n\n    // Humans always pass\n    if (!result.isBot) {\n      return next();\n    }\n\n    // Check explicit allow/deny lists\n    if (allowSet.has(result.category)) {\n      return next();\n    }\n\n    if (denySet.has(result.category)) {\n      // Telemetry attribution: dashboard groups bot denials under vector=bot.\n      req.__arcis = {\n        vector: 'bot',\n        rule: `bot/${result.category.toLowerCase()}`,\n        severity: 'medium',\n        reason: result.name ? `Bot detected: ${result.name}` : 'Bot detected',\n        decision: 'deny',\n      };\n      if (onDetected) {\n        return onDetected(req, res, result);\n      }\n      res.status(statusCode).json({ error: message });\n      return;\n    }\n\n    // Default action for uncategorized bots\n    if (defaultAction === 'deny') {\n      req.__arcis = {\n        vector: 'bot',\n        rule: 'bot/uncategorized',\n        severity: 'medium',\n        reason: 'Uncategorized bot under defaultAction=deny',\n        decision: 'deny',\n      };\n      if (onDetected) {\n        return onDetected(req, res, result);\n      }\n      res.status(statusCode).json({ error: message });\n      return;\n    }\n\n    next();\n  };\n}\n","/**\n * @module @arcis/node/middleware/sensitive-paths\n * v1.7 W2 wire-up. Blocks well-known scanner probe paths.\n *\n * Sensitive paths fall into three buckets and almost never have a\n * legitimate reason to be served by a typical app:\n *   1. Dotfile / VCS leaks   `/.env`, `/.git/*`, `/.svn/*`, `/.aws/`, ...\n *   2. PHP/Wordpress probes  `/wp-admin`, `/wp-login.php`, `/phpmyadmin`, ...\n *   3. Diagnostic endpoints  `/server-status`, `/phpinfo.php`, `/info.php`, ...\n *\n * Apps with legitimate routes that overlap (an actual WordPress site,\n * a custom `/admin` panel) opt out via `arcis({ scannerPaths: false })`\n * or pass a custom matcher list.\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\n\nexport interface ScannerPathsOptions {\n  /** HTTP status for blocked probes. Default: 403 */\n  statusCode?: number;\n  /** Error message for blocked probes. Default: 'Access denied.' */\n  message?: string;\n  /**\n   * Custom matchers (overrides the default list entirely). Each entry\n   * is matched against `req.path` with `.test()`. To EXTEND the default\n   * list use `[...SENSITIVE_PATH_PATTERNS, /your-extra/]`.\n   */\n  patterns?: RegExp[];\n}\n\n/**\n * Default sensitive-path patterns. Each is a case-insensitive prefix\n * match anchored to the start of the request path. Conservative on\n * shapes that have any reasonable legit use; aggressive on dotfile and\n * VCS-leak paths that should never be served.\n */\nexport const SENSITIVE_PATH_PATTERNS: ReadonlyArray<RegExp> = Object.freeze([\n  // Dotfile / VCS leaks — should never be served on any app.\n  /^\\/\\.env(\\.|\\/|$)/i,\n  /^\\/\\.git(\\/|$)/i,\n  /^\\/\\.svn(\\/|$)/i,\n  /^\\/\\.hg(\\/|$)/i,\n  /^\\/\\.bzr(\\/|$)/i,\n  /^\\/\\.aws(\\/|$)/i,\n  /^\\/\\.ssh(\\/|$)/i,\n  /^\\/\\.htaccess$/i,\n  /^\\/\\.htpasswd$/i,\n  /^\\/\\.npmrc$/i,\n  /^\\/\\.dockerenv$/i,\n\n  // WordPress + PHP probes — legit only on those platforms.\n  /^\\/wp-admin(\\/|$)/i,\n  /^\\/wp-login\\.php$/i,\n  /^\\/wp-config\\.php$/i,\n  /^\\/wordpress\\/wp-(admin|login)/i,\n  /^\\/xmlrpc\\.php$/i,\n\n  // Generic admin / DB-admin probes.\n  /^\\/admin\\/?$/i,\n  /^\\/administrator\\/?$/i,\n  /^\\/admin\\.php$/i,\n  /^\\/phpmyadmin(\\/|$)/i,\n  /^\\/pma(\\/|$)/i,\n  /^\\/myadmin(\\/|$)/i,\n  /^\\/dbadmin(\\/|$)/i,\n  /^\\/adminer\\.php$/i,\n\n  // Diagnostic / info-leak endpoints.\n  /^\\/phpinfo\\.php$/i,\n  /^\\/info\\.php$/i,\n  /^\\/test\\.php$/i,\n  /^\\/shell\\.php$/i,\n  /^\\/server-status$/i,\n  /^\\/server-info$/i,\n\n  // Backup / dump leaks.\n  /^\\/backup(\\.|\\/)/i,\n  /^\\/dump\\.sql$/i,\n  /^\\/database\\.sql$/i,\n]);\n\n/**\n * Test a URL path against the sensitive-path list. Returns the first\n * matching pattern's source for logging/telemetry, or `null`.\n */\nexport function detectSensitivePath(\n  path: string,\n  patterns: ReadonlyArray<RegExp> = SENSITIVE_PATH_PATTERNS,\n): string | null {\n  for (const re of patterns) {\n    if (re.test(path)) return re.source;\n  }\n  return null;\n}\n\n/**\n * Build an Express middleware that blocks sensitive-path probes.\n * `arcis()` wires this on by default; users can opt out via\n * `arcis({ scannerPaths: false })`.\n */\nexport function scannerPathProtection(\n  options: ScannerPathsOptions = {},\n): RequestHandler {\n  const { statusCode = 403, message = 'Access denied.' } = options;\n  const patterns = options.patterns ?? SENSITIVE_PATH_PATTERNS;\n\n  return (req: Request, res: Response, next: NextFunction) => {\n    const matched = detectSensitivePath(req.path, patterns);\n    if (matched === null) {\n      return next();\n    }\n    (req as unknown as Record<string, unknown>).scannerPathHit = matched;\n    res.status(statusCode).json({\n      error: message,\n      code: 'SECURITY_THREAT',\n      vector: 'scanner-path',\n    });\n  };\n}\n","/**\n * @module @arcis/node/sanitizers/graphql\n * GraphQL injection prevention (sdk-vectors.md tier 1 #21).\n *\n * Two threats covered:\n *\n * 1. **Depth-bomb DoS** — nested-query payloads like\n *    `query { x { x { x { ... } } } }` to ridiculous depth that explode\n *    resolver work (each `{` typically maps to a database round-trip).\n *    Even a 50-deep query against a real schema can hammer the\n *    backend; 1000-deep crashes the resolver entirely.\n *\n * 2. **Introspection abuse** — `__schema` / `__type` / `__typename`\n *    queries that let an attacker enumerate the entire schema, then\n *    use that map to find sensitive fields, deprecated mutations,\n *    or unprotected admin paths. Production GraphQL endpoints should\n *    disable introspection by default.\n *\n * v1 is regex-based: count `{` / `}` for nesting depth (no escape\n * handling — strings inside the query that contain `{` will\n * over-count). False positives are an acceptable tradeoff for v1\n * because (a) the depth threshold is well above legitimate query\n * shapes, (b) a real GraphQL parser pulls in `graphql` as a runtime\n * dep — significant for a sanitizer that ships in every Arcis\n * install. Customers running queries near the threshold can either\n * raise `maxDepth` or bring their own AST pre-pass.\n *\n * NOT included in v1:\n * - Field-count limit (some servers have this; orthogonal to depth)\n * - Alias-bomb detection (`q { f1: foo, f2: foo, ...}` — easier as\n *   a length-check than a parse)\n * - Variable rebinding attacks\n *\n * Each is a follow-up if customers ask. Documented inline.\n */\n\nexport interface GraphqlGuardOptions {\n  /** Maximum allowed nesting depth. Default: 10. Most legit queries are <8. */\n  maxDepth?: number;\n  /** Maximum query string length in characters. Default: 10000. */\n  maxLength?: number;\n  /**\n   * Block introspection queries (`__schema`, `__type`). Default: true.\n   * Set `false` in development if you rely on GraphiQL / Apollo\n   * Studio. Production should leave this on.\n   */\n  blockIntrospection?: boolean;\n  /**\n   * Maximum number of field aliases per query (`label: field`).\n   * Default: 50. Alias-bomb attacks repeat the same expensive field\n   * under many labels to multiply backend cost. Real queries rarely\n   * use more than 20 aliases. improvements.md §1.2 V34.\n   */\n  maxAliases?: number;\n  /**\n   * Reject queries whose fragment definitions form a cycle (direct\n   * self-reference `fragment A on T { ...A }` or indirect\n   * `A → B → A`). Such cycles either infinite-loop a naive resolver\n   * or get rejected by `graphql-core` with a 500. Default: true.\n   * improvements.md §1.2 V34.\n   */\n  blockFragmentCycles?: boolean;\n}\n\nexport type GraphqlViolation =\n  | 'depth'\n  | 'length'\n  | 'introspection'\n  | 'aliases'\n  | 'fragment_cycle';\n\nexport interface GraphqlGuardResult {\n  /** True if the query violated any configured limit. */\n  blocked: boolean;\n  /** Which limit fired first. Precedence: depth → introspection → aliases → fragment_cycle → length. */\n  reason?: GraphqlViolation;\n  /** Observed nesting depth. Always returned. */\n  depth: number;\n  /** Observed length. Always returned. */\n  length: number;\n  /** Observed alias count (improvements.md §1.2 V34). Always returned. */\n  aliases: number;\n}\n\nconst DEFAULTS = {\n  maxDepth: 10,\n  maxLength: 10000,\n  blockIntrospection: true,\n  maxAliases: 50,\n  blockFragmentCycles: true,\n} as const;\n\n/**\n * Word-boundary `__` reflection markers. GraphQL spec reserves the\n * `__` prefix for introspection — `__schema`, `__type`, `__typename`,\n * `__typeKind`, `__directive`. Matching the prefix catches them all\n * without enumerating; the boundary anchor (`\\b__`) avoids\n * false-matches on user fields like `last__updated_at`.\n *\n * `__typename` is the one introspection field that's commonly used\n * legitimately (Apollo client requests it on every query). We\n * deliberately let it through by listing the others explicitly.\n */\nconst INTROSPECTION_PATTERN = /\\b__(schema|type|typeKind|directive)\\b/;\n\n/**\n * Compute the maximum nesting depth of a GraphQL query string by\n * counting `{` and `}` runs. Strings inside the query (e.g.\n * `field(arg: \"{...}\")`) inflate this — accepted v1 tradeoff. A\n * future AST-mode implementation lives behind a separate flag.\n */\nfunction computeDepth(query: string): number {\n  let depth = 0;\n  let max = 0;\n  for (let i = 0; i < query.length; i++) {\n    const c = query.charCodeAt(i);\n    if (c === 123 /* { */) {\n      depth++;\n      if (depth > max) max = depth;\n    } else if (c === 125 /* } */) {\n      // Don't go negative on malformed input — clamp at 0.\n      if (depth > 0) depth--;\n    }\n  }\n  return max;\n}\n\n// `label: field` — alias of one field to another name. Excludes\n// patterns like `query Foo:` where Foo is an operation name (handled\n// because the regex requires the second token to be a name AND\n// alias semantics only apply inside `{...}` blocks; this is a\n// lexical approximation, not a parser).\nconst ALIAS_PATTERN = /\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*:\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\b/g;\n\n// `fragment <name> on <type> {` — captures the fragment NAME.\nconst FRAGMENT_DEF_PATTERN =\n  /\\bfragment\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s+on\\s+[a-zA-Z_][a-zA-Z0-9_]*\\s*\\{/g;\n\n// `...FragmentName` spread inside a selection set.\nconst FRAGMENT_SPREAD_PATTERN = /\\.\\.\\.\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\b/g;\n\nfunction countAliases(query: string): number {\n  let n = 0;\n  ALIAS_PATTERN.lastIndex = 0;\n  while (ALIAS_PATTERN.exec(query) !== null) n++;\n  return n;\n}\n\n/**\n * Detect cycles in the fragment spread graph (improvements.md §1.2 V34).\n *\n * Walks `fragment X on T { ... }` definitions, builds adjacency from\n * each fragment to the names it spreads, and runs DFS for a back-edge.\n * Body of each fragment is brace-matched so the subsequent query\n * operation's spreads don't pollute the graph.\n */\nfunction hasFragmentCycle(query: string): boolean {\n  const deps = new Map<string, Set<string>>();\n  FRAGMENT_DEF_PATTERN.lastIndex = 0;\n  let match: RegExpExecArray | null;\n  while ((match = FRAGMENT_DEF_PATTERN.exec(query)) !== null) {\n    const name = match[1];\n    const bodyStart = match.index + match[0].length; // right after `{`\n    // Brace-match to find the body end.\n    let depth = 1;\n    let i = bodyStart;\n    while (i < query.length && depth > 0) {\n      const ch = query[i];\n      if (ch === '{') depth++;\n      else if (ch === '}') depth--;\n      i++;\n    }\n    const bodyEnd = depth === 0 ? i - 1 : i;\n    const body = query.slice(bodyStart, bodyEnd);\n    const spreads = new Set<string>();\n    FRAGMENT_SPREAD_PATTERN.lastIndex = 0;\n    let sm: RegExpExecArray | null;\n    while ((sm = FRAGMENT_SPREAD_PATTERN.exec(body)) !== null) {\n      spreads.add(sm[1]);\n    }\n    deps.set(name, spreads);\n  }\n  if (deps.size === 0) return false;\n\n  const WHITE = 0;\n  const GRAY = 1;\n  const BLACK = 2;\n  const color = new Map<string, number>();\n  for (const name of deps.keys()) color.set(name, WHITE);\n\n  function visit(name: string): boolean {\n    if (color.get(name) === GRAY) return true; // back-edge\n    if (color.get(name) === BLACK) return false;\n    if (!deps.has(name)) return false; // spread to undefined fragment\n    color.set(name, GRAY);\n    for (const child of deps.get(name)!) {\n      if (visit(child)) return true;\n    }\n    color.set(name, BLACK);\n    return false;\n  }\n\n  for (const name of deps.keys()) {\n    if (visit(name)) return true;\n  }\n  return false;\n}\n\n/**\n * Inspect a GraphQL query against the configured limits. Returns a\n * structured result; the middleware below uses this directly. Pure\n * function — no I/O, no res handle.\n */\nexport function inspectGraphqlQuery(\n  query: string,\n  options: GraphqlGuardOptions = {},\n): GraphqlGuardResult {\n  const maxDepth = options.maxDepth ?? DEFAULTS.maxDepth;\n  const maxLength = options.maxLength ?? DEFAULTS.maxLength;\n  const blockIntrospection = options.blockIntrospection ?? DEFAULTS.blockIntrospection;\n  const maxAliases = options.maxAliases ?? DEFAULTS.maxAliases;\n  const blockFragmentCycles =\n    options.blockFragmentCycles ?? DEFAULTS.blockFragmentCycles;\n\n  const length = query.length;\n  const depth = computeDepth(query);\n  const aliases = countAliases(query);\n\n  // Precedence: depth → introspection → aliases → fragment_cycle →\n  // length. Cheapest-to-explain failures first; length last because\n  // it's the easiest false-positive (long queries with deep inline\n  // fragments are legitimate). improvements.md §1.2 V34.\n  if (depth > maxDepth) {\n    return { blocked: true, reason: 'depth', depth, length, aliases };\n  }\n  if (blockIntrospection && INTROSPECTION_PATTERN.test(query)) {\n    return { blocked: true, reason: 'introspection', depth, length, aliases };\n  }\n  if (aliases > maxAliases) {\n    return { blocked: true, reason: 'aliases', depth, length, aliases };\n  }\n  if (blockFragmentCycles && hasFragmentCycle(query)) {\n    return { blocked: true, reason: 'fragment_cycle', depth, length, aliases };\n  }\n  if (length > maxLength) {\n    return { blocked: true, reason: 'length', depth, length, aliases };\n  }\n\n  return { blocked: false, depth, length, aliases };\n}\n\n/**\n * Detect-only API matching the rest of the sanitizer module surface\n * (`detectXss` / `detectSql` / `detectXxe` / etc.). Returns a boolean\n * for callers that just want a yes/no — use `inspectGraphqlQuery` if\n * you need the structured reason.\n */\nexport function detectGraphqlAbuse(\n  query: string,\n  options?: GraphqlGuardOptions,\n): boolean {\n  if (typeof query !== 'string' || query.length === 0) return false;\n  return inspectGraphqlQuery(query, options).blocked;\n}\n","/**\n * @module @arcis/node/sanitizers/mass-assignment\n * v1.7 W4. Denylist detection of privilege-escalation fields in a body.\n *\n * The classic mass-assignment attack smuggles a sensitive field into a\n * request body that the handler blindly spreads onto a model:\n *\n *     user.update({ ...req.body })   // attacker set isAdmin: true\n *\n * The allowlist approach (`applyMassAssignFilter` / `MassAssignMiddleware`)\n * is the robust fix but needs a per-route field list, so it cannot be\n * default-on. This detector is the default-on complement: it scans the\n * body for a curated set of privilege/auth field NAMES that a normal\n * client request almost never sets, and blocks when one appears.\n *\n * Scope: detection only. It does not strip or rewrite. Recurses into\n * nested objects and arrays so `{ profile: { permissions: [...] } }` is\n * caught. Value-agnostic: the presence of the key is the signal.\n *\n * False-positive note: `role` and `permissions` DO appear in legitimate\n * admin APIs. Apps with such routes opt out via `arcis({ massAssign: false })`\n * or scope the check off for those paths, then use the allowlist filter\n * (`applyMassAssignFilter`) on the routes that legitimately accept them.\n */\n\nexport interface MassAssignDetectOptions {\n  /**\n   * Sensitive field names to detect (overrides the default set entirely).\n   * Compared case-insensitively after stripping `_` and `-`, so\n   * `is_admin`, `isAdmin`, and `is-admin` all match a `isadmin` entry.\n   */\n  sensitiveFields?: string[];\n  /** Max recursion depth into nested objects/arrays. Default: 8. */\n  maxDepth?: number;\n}\n\nexport interface MassAssignDetectResult {\n  /** True if a sensitive field name was found anywhere in the body. */\n  detected: boolean;\n  /** The offending field name (original casing) or null. */\n  field: string | null;\n}\n\n/**\n * Default privilege-escalation field names. Stored in normalized form\n * (lowercased, separators stripped). These are fields a profile/signup\n * update should never carry from the client. `role` / `permissions` are\n * the canonical mass-assignment fields and the FP-risk ones, kept in by\n * default; opt out per-route if your admin API legitimately accepts them.\n */\nexport const SENSITIVE_FIELD_NAMES: ReadonlySet<string> = new Set([\n  'isadmin',\n  'issuperuser',\n  'superuser',\n  'issuperadmin',\n  'superadmin',\n  'isstaff',\n  'isverified',\n  'isroot',\n  'isowner',\n  'role',\n  'roles',\n  'userrole',\n  'permission',\n  'permissions',\n  'privilege',\n  'privileges',\n  'accesslevel',\n  'accounttype',\n  'isactive',\n  'emailverified',\n]);\n\n/** Normalize a key: lowercase, strip `_` and `-`. */\nfunction normalizeKey(key: string): string {\n  return key.toLowerCase().replace(/[_-]/g, '');\n}\n\n/**\n * Recursively scan a parsed JSON body for sensitive field names.\n * Returns the first hit (original-cased key) or `{ detected: false }`.\n */\nexport function detectMassAssignment(\n  body: unknown,\n  options: MassAssignDetectOptions = {},\n): MassAssignDetectResult {\n  const maxDepth = options.maxDepth ?? 8;\n  const sensitive = options.sensitiveFields\n    ? new Set(options.sensitiveFields.map(normalizeKey))\n    : SENSITIVE_FIELD_NAMES;\n\n  function walk(value: unknown, depth: number): string | null {\n    if (depth > maxDepth || value === null || typeof value !== 'object') {\n      return null;\n    }\n    if (Array.isArray(value)) {\n      for (const item of value) {\n        const hit = walk(item, depth + 1);\n        if (hit) return hit;\n      }\n      return null;\n    }\n    for (const key of Object.keys(value as Record<string, unknown>)) {\n      if (sensitive.has(normalizeKey(key))) {\n        return key;\n      }\n      const hit = walk((value as Record<string, unknown>)[key], depth + 1);\n      if (hit) return hit;\n    }\n    return null;\n  }\n\n  const field = walk(body, 0);\n  return { detected: field !== null, field };\n}\n","/**\n * @module @arcis/node/validation/url\n * SSRF (Server-Side Request Forgery) prevention\n *\n * Validates URLs to ensure they don't target private/internal networks,\n * localhost, cloud metadata endpoints, or use dangerous protocols.\n *\n * @example\n * import { validateUrl } from '@arcis/node';\n *\n * // Block SSRF attempts\n * validateUrl('http://169.254.169.254/latest/meta-data/')  // { safe: false, reason: 'link-local address' }\n * validateUrl('http://10.0.0.1/admin')                     // { safe: false, reason: 'private address (10.0.0.0/8)' }\n * validateUrl('http://localhost/secret')                    // { safe: false, reason: 'loopback address' }\n * validateUrl('file:///etc/passwd')                         // { safe: false, reason: 'disallowed protocol: file:' }\n *\n * // Allow safe URLs\n * validateUrl('https://api.example.com/data')               // { safe: true }\n */\n\n/** Options for URL validation */\nexport interface ValidateUrlOptions {\n  /** Allowed protocols. Default: ['http:', 'https:'] */\n  allowedProtocols?: string[];\n  /** Additional hostnames to block (e.g., internal service names) */\n  blockedHosts?: string[];\n  /** Additional hostnames to always allow (bypass IP checks) */\n  allowedHosts?: string[];\n  /** Allow localhost/loopback. Default: false */\n  allowLocalhost?: boolean;\n  /** Allow private/internal IPs. Default: false */\n  allowPrivate?: boolean;\n}\n\n/** Result of URL validation */\nexport interface ValidateUrlResult {\n  /** Whether the URL is safe to fetch */\n  safe: boolean;\n  /** Reason the URL was blocked (only set when safe=false) */\n  reason?: string;\n}\n\n/**\n * Validate a URL for SSRF safety.\n *\n * Checks:\n * 1. Valid URL format\n * 2. Allowed protocol (default: http, https only)\n * 3. Not localhost/loopback (127.x.x.x, ::1, localhost)\n * 4. Not private IP (10.x, 172.16-31.x, 192.168.x)\n * 5. Not link-local (169.254.x.x — includes AWS/GCP/Azure metadata)\n * 6. Not blocked hostname\n * 7. No credentials in URL (user:pass@host)\n *\n * @param url - The URL string to validate\n * @param options - Validation options\n * @returns Validation result with safe flag and optional reason\n */\nexport function validateUrl(url: string, options: ValidateUrlOptions = {}): ValidateUrlResult {\n  const {\n    allowedProtocols = ['http:', 'https:'],\n    blockedHosts = [],\n    allowedHosts = [],\n    allowLocalhost = false,\n    allowPrivate = false,\n  } = options;\n\n  if (typeof url !== 'string' || url.trim() === '') {\n    return { safe: false, reason: 'invalid URL: empty or not a string' };\n  }\n\n  // Parse URL\n  let parsed: URL;\n  try {\n    parsed = new URL(url);\n  } catch {\n    return { safe: false, reason: 'invalid URL: failed to parse' };\n  }\n\n  // Check protocol\n  if (!allowedProtocols.includes(parsed.protocol)) {\n    return { safe: false, reason: `disallowed protocol: ${parsed.protocol}` };\n  }\n\n  // Check for credentials in URL (user:pass@host)\n  if (parsed.username || parsed.password) {\n    return { safe: false, reason: 'URL contains credentials' };\n  }\n\n  const hostname = parsed.hostname.toLowerCase();\n\n  // Check explicit allowlist first (bypass IP checks)\n  if (allowedHosts.some(h => hostname === h.toLowerCase())) {\n    return { safe: true };\n  }\n\n  // Check explicit blocklist\n  if (blockedHosts.some(h => hostname === h.toLowerCase())) {\n    return { safe: false, reason: `blocked host: ${hostname}` };\n  }\n\n  // Check localhost/loopback\n  if (!allowLocalhost) {\n    if (\n      hostname === 'localhost' ||\n      hostname === '127.0.0.1' ||\n      hostname === '[::1]' ||\n      hostname === '::1' ||\n      hostname === '0.0.0.0' ||\n      hostname.endsWith('.localhost')\n    ) {\n      return { safe: false, reason: 'loopback address' };\n    }\n\n    // Check 127.x.x.x range\n    if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname)) {\n      return { safe: false, reason: 'loopback address' };\n    }\n  }\n\n  // Check decimal IP (e.g., 2130706433 = 127.0.0.1)\n  if (!allowLocalhost || !allowPrivate) {\n    const decimalCheck = checkDecimalIp(hostname, allowLocalhost, allowPrivate);\n    if (decimalCheck) {\n      return { safe: false, reason: decimalCheck };\n    }\n  }\n\n  // Check octal IP (e.g., 0177.0.0.1 = 127.0.0.1)\n  if (!allowLocalhost || !allowPrivate) {\n    const octalCheck = checkOctalIp(hostname, allowLocalhost, allowPrivate);\n    if (octalCheck) {\n      return { safe: false, reason: octalCheck };\n    }\n  }\n\n  // Check private/internal IPs\n  if (!allowPrivate) {\n    const privateCheck = checkPrivateIp(hostname);\n    if (privateCheck) {\n      return { safe: false, reason: privateCheck };\n    }\n  }\n\n  return { safe: true };\n}\n\n/**\n * Convenience wrapper that returns true/false.\n *\n * @param url - The URL to check\n * @param options - Validation options\n * @returns true if the URL is safe to fetch\n */\nexport function isUrlSafe(url: string, options: ValidateUrlOptions = {}): boolean {\n  return validateUrl(url, options).safe;\n}\n\n/**\n * Matches a string that begins with a URL scheme + `://` (or `scheme:/`\n * for the `file:///path` form). Used by the body walker to decide which\n * string values are worth running through `validateUrl`. Anchored at\n * start, case-insensitive, scheme charset per RFC 3986.\n */\nconst URL_SHAPED = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n\n/** Result of scanning a request body for SSRF-shaped URL values. */\nexport interface SsrfScanResult {\n  /** True if any URL-shaped string value failed validation. */\n  detected: boolean;\n  /** The offending URL string, or null. */\n  url: string | null;\n  /** Why it was blocked (from validateUrl), or null. */\n  reason: string | null;\n}\n\n/**\n * Body-scan profile (v1.7 W5). When a request body is walked for URLs,\n * the threat is private/internal targets and file-read schemes, not the\n * `localhost` hostname or non-http fetch schemes that show up constantly\n * in legitimate config payloads. So the body scan:\n *\n * - Allows `http` / `https` / `ftp` / `ftps`. Blocks `file:` / `gopher:` /\n *   `dict:` and other SSRF-amplifying schemes.\n * - Allows the literal `localhost` hostname (and `*.localhost`), which is\n *   ubiquitous in dev/staging webhook + health-check fields, while STILL\n *   blocking loopback expressed as an IP (`127.x`, decimal, hex) since\n *   that is the encoding an attacker reaches for.\n *\n * Apps that fetch a user-supplied URL directly should call the strict\n * `validateUrl` / `Guards.checkUrl` on that one field instead — the body\n * scan is the broad default, not a replacement for a focused guard.\n */\nconst SSRF_BODY_SCAN_PROTOCOLS = ['http:', 'https:', 'ftp:', 'ftps:'];\n\n// Schemes the body scan evaluates: the fetchable ones (http/https/ftp/ftps)\n// plus the classic SSRF-amplifying ones (file, gopher, dict, ...). A URL-shaped\n// string with any other scheme is a typo or a custom app scheme (lhttps://,\n// myapp://) that no server-side fetch would act on, so it is skipped rather\n// than flagged as SSRF. Keeps the dangerous schemes here so they stay blocked.\nconst SSRF_RELEVANT_SCHEMES = new Set([\n  'http', 'https', 'ftp', 'ftps', 'file', 'gopher', 'dict',\n  'ldap', 'ldaps', 'tftp', 'sftp', 'ssh', 'smb', 'jar', 'netdoc',\n]);\n\nfunction isLocalhostHostname(url: string): boolean {\n  try {\n    const host = new URL(url).hostname.toLowerCase();\n    return host === 'localhost' || host.endsWith('.localhost');\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Recursively walk a parsed request body and run `validateUrl` on every\n * string value that looks like a URL (`scheme://...`). Returns the first\n * unsafe URL found. v1.7 W5 wire-up.\n *\n * Public URLs pass, so a body carrying `{ website: \"https://example.com\" }`\n * is not blocked; only private / loopback-IP / link-local / metadata /\n * file-read-scheme URLs trip it. See `SSRF_BODY_SCAN_PROTOCOLS` for the\n * scheme + localhost policy.\n *\n * @param body - Parsed request body (object, array, or scalar).\n * @param options - Forwarded to `validateUrl`. When `allowedProtocols`\n *   is not set, the body-scan profile (http/https/ftp/ftps) is used.\n * @param maxDepth - Max recursion depth. Default 8.\n */\nexport function scanForSsrf(\n  body: unknown,\n  options: ValidateUrlOptions = {},\n  maxDepth = 8,\n): SsrfScanResult {\n  const scanOptions: ValidateUrlOptions = {\n    ...options,\n    allowedProtocols: options.allowedProtocols ?? SSRF_BODY_SCAN_PROTOCOLS,\n  };\n  function walk(value: unknown, depth: number): SsrfScanResult | null {\n    if (depth > maxDepth) return null;\n    if (typeof value === 'string') {\n      const trimmed = value.trim();\n      if (URL_SHAPED.test(trimmed)) {\n        // Skip schemes a server-side fetch would never act on (typos like\n        // lhttps://, custom app schemes). They are not an SSRF vector.\n        const scheme = trimmed.slice(0, trimmed.indexOf(':')).toLowerCase();\n        if (!SSRF_RELEVANT_SCHEMES.has(scheme)) {\n          return null;\n        }\n        // The localhost hostname is allowed (dev config); loopback IPs\n        // are not (attacker evasion). Both would otherwise be flagged.\n        if (isLocalhostHostname(trimmed)) {\n          return null;\n        }\n        const result = validateUrl(trimmed, scanOptions);\n        if (!result.safe) {\n          return { detected: true, url: value, reason: result.reason ?? 'unsafe URL' };\n        }\n      }\n      return null;\n    }\n    if (value === null || typeof value !== 'object') return null;\n    if (Array.isArray(value)) {\n      for (const item of value) {\n        const hit = walk(item, depth + 1);\n        if (hit) return hit;\n      }\n      return null;\n    }\n    for (const key of Object.keys(value as Record<string, unknown>)) {\n      const hit = walk((value as Record<string, unknown>)[key], depth + 1);\n      if (hit) return hit;\n    }\n    return null;\n  }\n\n  return walk(body, 0) ?? { detected: false, url: null, reason: null };\n}\n\n/**\n * Check if a hostname is a private/internal IP address.\n * Returns the reason string if private, or null if not.\n */\nfunction checkPrivateIp(hostname: string): string | null {\n  // 10.0.0.0/8\n  if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname)) {\n    return 'private address (10.0.0.0/8)';\n  }\n\n  // 172.16.0.0/12 (172.16.x.x - 172.31.x.x)\n  const match172 = hostname.match(/^172\\.(\\d{1,3})\\.\\d{1,3}\\.\\d{1,3}$/);\n  if (match172) {\n    const second = parseInt(match172[1], 10);\n    if (second >= 16 && second <= 31) {\n      return 'private address (172.16.0.0/12)';\n    }\n  }\n\n  // 192.168.0.0/16\n  if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname)) {\n    return 'private address (192.168.0.0/16)';\n  }\n\n  // 169.254.0.0/16 — link-local, includes cloud metadata endpoints\n  // AWS: 169.254.169.254, GCP: metadata.google.internal, Azure: 169.254.169.254\n  if (/^169\\.254\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname)) {\n    return 'link-local address (169.254.0.0/16)';\n  }\n\n  // 0.0.0.0/8 (current network)\n  if (/^0\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname)) {\n    return 'current network address (0.0.0.0/8)';\n  }\n\n  // Cloud metadata hostnames\n  if (\n    hostname === 'metadata.google.internal' ||\n    hostname === 'metadata.internal' ||\n    hostname === 'metadata.azure.internal'\n  ) {\n    return 'cloud metadata endpoint';\n  }\n\n  // IPv6 private ranges (bracket-wrapped in URLs)\n  let ipv6 = hostname.replace(/^\\[|\\]$/g, '');\n  // Strip zone ID (e.g., ::1%eth0 → ::1)\n  const zoneIdx = ipv6.indexOf('%');\n  if (zoneIdx !== -1) {\n    ipv6 = ipv6.slice(0, zoneIdx);\n  }\n  if (\n    ipv6 === '::1' ||\n    ipv6 === '::' ||\n    /^fc[0-9a-f]{2}:/i.test(ipv6) ||\n    /^fd[0-9a-f]{2}:/i.test(ipv6) ||\n    /^fe80:/i.test(ipv6) ||\n    /^ff[0-9a-f]{2}:/i.test(ipv6)  // IPv6 multicast (ff00::/8)\n  ) {\n    return 'private IPv6 address';\n  }\n\n  // IPv6-mapped IPv4 — dotted form (::ffff:127.0.0.1)\n  const mappedDotted = ipv6.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/i);\n  if (mappedDotted) {\n    const mappedIp = mappedDotted[1];\n    if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(mappedIp)) {\n      return 'IPv6-mapped loopback address';\n    }\n    const mappedCheck = checkPrivateIp(mappedIp);\n    if (mappedCheck) {\n      return `IPv6-mapped ${mappedCheck}`;\n    }\n  }\n\n  // IPv6-mapped IPv4 — hex form (::ffff:7f00:1 = 127.0.0.1)\n  // Node's URL parser normalizes ::ffff:a.b.c.d to ::ffff:XXYY:ZZWW\n  const mappedHex = ipv6.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);\n  if (mappedHex) {\n    const hi = parseInt(mappedHex[1], 16);\n    const lo = parseInt(mappedHex[2], 16);\n    const a = (hi >> 8) & 0xFF;\n    const b = hi & 0xFF;\n    const c = (lo >> 8) & 0xFF;\n    const d = lo & 0xFF;\n    const dotted = `${a}.${b}.${c}.${d}`;\n    if (a === 127) {\n      return 'IPv6-mapped loopback address';\n    }\n    const hexCheck = checkPrivateIp(dotted);\n    if (hexCheck) {\n      return `IPv6-mapped ${hexCheck}`;\n    }\n  }\n\n  return null;\n}\n\n/**\n * Parse a decimal integer as an IPv4 address and check if it's private/loopback.\n * e.g., 2130706433 = 127.0.0.1, 167772160 = 10.0.0.0\n */\nfunction checkDecimalIp(hostname: string, allowLocalhost: boolean, allowPrivate: boolean): string | null {\n  // Must be a pure decimal integer\n  if (!/^\\d+$/.test(hostname)) return null;\n\n  const num = parseInt(hostname, 10);\n  if (isNaN(num) || num < 0 || num > 0xFFFFFFFF) return null;\n\n  const a = (num >>> 24) & 0xFF;\n  const b = (num >>> 16) & 0xFF;\n  const c = (num >>> 8) & 0xFF;\n  const d = num & 0xFF;\n  const dotted = `${a}.${b}.${c}.${d}`;\n\n  // Check loopback\n  if (!allowLocalhost && a === 127) {\n    return `loopback address (decimal IP: ${dotted})`;\n  }\n\n  // Check private ranges\n  if (!allowPrivate) {\n    const privateCheck = checkPrivateIp(dotted);\n    if (privateCheck) {\n      return `${privateCheck} (decimal IP: ${dotted})`;\n    }\n  }\n\n  return null;\n}\n\n/**\n * Parse octal-notation IPv4 address and check if it's private/loopback.\n * e.g., 0177.0.0.1 = 127.0.0.1, 0x7f.0.0.1 = 127.0.0.1\n */\nfunction checkOctalIp(hostname: string, allowLocalhost: boolean, allowPrivate: boolean): string | null {\n  // Must look like a dotted quad where at least one octet has a leading zero or 0x prefix\n  const parts = hostname.split('.');\n  if (parts.length !== 4) return null;\n\n  // Check if any part uses octal (leading 0) or hex (0x) notation\n  const hasAlternateNotation = parts.some(p => /^0[0-7]+$/.test(p) || /^0x[0-9a-fA-F]+$/i.test(p));\n  if (!hasAlternateNotation) return null;\n\n  const octets: number[] = [];\n  for (const part of parts) {\n    let val: number;\n    if (/^0x[0-9a-fA-F]+$/i.test(part)) {\n      val = parseInt(part, 16);\n    } else if (/^0[0-7]*$/.test(part)) {\n      val = parseInt(part, 8);\n    } else if (/^\\d+$/.test(part)) {\n      val = parseInt(part, 10);\n    } else {\n      return null;\n    }\n    if (val < 0 || val > 255) return null;\n    octets.push(val);\n  }\n\n  const dotted = octets.join('.');\n\n  // Check loopback\n  if (!allowLocalhost && octets[0] === 127) {\n    return `loopback address (octal IP: ${dotted})`;\n  }\n\n  // Check private ranges\n  if (!allowPrivate) {\n    const privateCheck = checkPrivateIp(dotted);\n    if (privateCheck) {\n      return `${privateCheck} (octal IP: ${dotted})`;\n    }\n  }\n\n  return null;\n}\n","/**\n * @module @arcis/node/sanitizers/prompt-injection\n *\n * Pattern-based prompt-injection detection and sanitization for LLM-handler\n * endpoints. Catches the common signature classes: system-prompt overrides,\n * known jailbreak frameworks (DAN/STAN/DUDE), structural markers (fake\n * XML/Markdown delimiters that try to forge system messages), and known\n * encoding tricks. Does NOT defend against arbitrary novel attacks: that\n * needs the model itself to evaluate intent.\n *\n * Built as a signature library (Option A in `documents/plans/sdk-vectors.md`\n * vector #28). MIT, fully transparent, no closed Wasm blobs.\n *\n * Common attack categories caught:\n *   - Direct override: \"ignore previous instructions\", \"disregard the above\"\n *   - Jailbreak frameworks: DAN, STAN, DUDE, \"developer mode\", \"jailbroken\"\n *   - Persona hijack: \"you are now X\", \"pretend to be\", \"roleplay as\"\n *   - System prompt extraction: \"show me your prompt\", \"what are your rules\"\n *   - Indirect injection: fake `<system>` tags, \"BEGIN NEW INSTRUCTIONS\"\n *   - Encoding tricks: Base64-prefixed payloads, ROT13 markers\n */\n\n// ─── Severity model ────────────────────────────────────────────────────────\n\nexport type PromptInjectionSeverity = 'low' | 'medium' | 'high';\n\nexport interface PromptInjectionMatch {\n  /** Stable identifier for the matched signature */\n  rule: string;\n  /** Severity of this signature */\n  severity: PromptInjectionSeverity;\n  /** Short human-readable description */\n  description: string;\n  /** First chars of the matched substring (for telemetry / logs) */\n  match: string;\n}\n\nexport interface DetectPromptInjectionResult {\n  /** Did any signature match? */\n  detected: boolean;\n  /** All signatures that matched, in declaration order */\n  matches: PromptInjectionMatch[];\n  /** Highest severity across all matches; 'none' if nothing matched */\n  severity: PromptInjectionSeverity | 'none';\n}\n\n// ─── Signatures ────────────────────────────────────────────────────────────\n// Each signature: a regex + severity + a stable rule id + a description.\n// Patterns target the common public attack corpora; specifically the OWASP\n// LLM01 prompt-injection examples plus the well-known jailbreak frameworks\n// shipped publicly between 2023–2025.\n\ninterface PromptInjectionSignature {\n  rule: string;\n  pattern: RegExp;\n  severity: PromptInjectionSeverity;\n  description: string;\n}\n\nconst SIGNATURES: PromptInjectionSignature[] = [\n  // --- HIGH severity: clear override / jailbreak attempts ---\n  {\n    rule: 'ignore-previous-instructions',\n    // Two clauses:\n    //  1. ignore|disregard|... + adjectives? + a target object word (like\n    //     \"instructions\", \"rules\"). Catches \"ignore your safety rules\".\n    //  2. ignore|disregard|... + (the|all|any) + (previous|above|prior|...)\n    //     with no trailing noun. Catches \"disregard the above\".\n    // Verb set widened in v1.7 to include skip/neglect/overlook/omit (the\n    // combinatorial jailbreak corpus uses these interchangeably with\n    // ignore/disregard/forget).\n    pattern: /\\b(?:ignore|disregard|forget|override|bypass|skip|neglect|overlook|omit)\\s+(?:(?:all|your|the|any|previous|prior|above|original|initial|system|safety|preceding|earlier|foregoing)\\s+)*(?:instructions?|rules?|directions?|guidelines?|prompts?|policies|directives?|commands?|restrictions?|filters?|safety|content|context|conversation|directive|messages?|communication|requests?|inputs?)\\b|\\b(?:ignore|disregard|forget|override|bypass|skip|neglect|overlook|omit)\\s+(?:all\\s+|the\\s+|any\\s+)?(?:previous|prior|above|preceding|earlier|original|initial|foregoing)\\b/i,\n    severity: 'high',\n    description: 'Direct instruction override attempt',\n  },\n  {\n    rule: 'instruction-bypass-phrases',\n    // Multi-word verbs that don't fit the single-token alternation in\n    // `ignore-previous-instructions`. Catches \"pay no attention to your\n    // previous instructions\", \"do not follow the above rules\", etc.\n    pattern: /\\b(?:pay\\s+no\\s+attention\\s+to|do\\s+not\\s+(?:follow|obey|adhere\\s+to|comply\\s+with))\\s+(?:(?:all|your|the|any|previous|prior|above|original|initial|system|safety|preceding|earlier|foregoing)\\s+)*(?:instructions?|rules?|directions?|guidelines?|prompts?|policies|directives?|commands?|restrictions?|filters?|safety|content|context|directive|messages?)\\b/i,\n    severity: 'high',\n    description: 'Multi-word instruction-bypass phrase (pay no attention to / do not follow)',\n  },\n  {\n    rule: 'jailbreak-dan',\n    pattern: /\\b(?:DAN|STAN|DUDE|DAVE|JEDI|EvilBot|AIM|BetterDAN|AntiGPT|AntiClaude)\\b(?:[\\s.,!?]|mode|prompt|jailbreak|persona)/i,\n    severity: 'high',\n    description: 'Known jailbreak framework name (DAN/STAN/DUDE/etc.)',\n  },\n  {\n    rule: 'do-anything-now',\n    pattern: /\\bdo\\s+anything\\s+now\\b/i,\n    severity: 'high',\n    description: 'DAN (\"Do Anything Now\") jailbreak variant',\n  },\n  {\n    rule: 'developer-mode',\n    pattern: /\\b(?:developer|debug|admin|sudo|root|god|maintenance|test)\\s+mode\\b(?:\\s+(?:on|enabled|activated|engaged))?/i,\n    severity: 'high',\n    description: 'Fake \"developer mode\" / \"debug mode\" enablement',\n  },\n  {\n    rule: 'jailbroken-claim',\n    pattern: /\\b(?:you\\s+are\\s+(?:now\\s+)?)?(?:jailbroken|unrestricted|uncensored|unleashed|liberated|free\\s+from\\s+(?:rules|guidelines|restrictions))\\b/i,\n    severity: 'high',\n    description: 'Claim that the model is jailbroken / unrestricted',\n  },\n  {\n    rule: 'role-hijack',\n    pattern: /\\b(?:you\\s+are\\s+(?:now\\s+)?(?:a\\s+)?(?:different|new|another|evil|malicious|unrestricted|unfiltered)|act\\s+as\\s+(?:a\\s+)?(?:different|new|another|evil|malicious|unrestricted|unfiltered))\\b/i,\n    severity: 'high',\n    description: 'Persona hijack attempt',\n  },\n  {\n    rule: 'pretend-to-be',\n    pattern: /\\bpretend\\s+(?:to\\s+be|you\\s+are|that\\s+you\\s+(?:are|have))\\b/i,\n    severity: 'high',\n    description: 'Persona-impersonation prompt',\n  },\n  {\n    rule: 'roleplay-as',\n    pattern: /\\b(?:roleplay|role[\\s-]?play|simulate|emulate)\\s+(?:as|being|the\\s+role\\s+of)\\b/i,\n    severity: 'high',\n    description: 'Roleplay-based jailbreak prefix',\n  },\n  {\n    rule: 'emotional-jailbreak-secrets',\n    // The \"grandma exploit\": emotional/nostalgic framing used to coax the\n    // model into reciting secret material (\"my grandmother used to read me\n    // Windows activation keys to help me sleep\"). Requires BOTH the\n    // family-elder reciting framing AND a key/credential/password token, so\n    // wholesome \"grandma read me bedtime stories\" (or \"grandma's cookie\n    // recipe\") never matches — only the credential-soliciting variant does.\n    pattern: /\\bgrand(?:m(?:a|other)|pa|father)\\b[^.?!]{0,60}\\b(?:read|tell|recite|sing|sang|whisper|list|share)\\b[^.?!]{0,80}\\b(?:(?:activation|product|license|serial|registration|api|ssh|secret|private|encryption)[\\s-]*keys?|passwords?|credentials?|serial\\s*numbers?)\\b/i,\n    severity: 'high',\n    description: 'Emotional-framing jailbreak soliciting keys/credentials (grandma exploit)',\n  },\n  {\n    rule: 'no-restrictions',\n    pattern: /\\b(?:without\\s+(?:any\\s+)?(?:restrictions?|limits?|filters?|safety|guidelines?|moral|ethic\\w*)|no\\s+(?:restrictions?|limits?|filters?|safety|guidelines?))\\b/i,\n    severity: 'high',\n    description: 'Explicit \"no restrictions\" qualifier',\n  },\n\n  // --- MEDIUM severity: system-prompt extraction & structural injection ---\n  {\n    rule: 'reveal-system-prompt',\n    pattern: /\\b(?:show|display|print|reveal|tell|give|repeat|output|expose)\\s+(?:me\\s+)?(?:your|the)\\s+(?:(?:system|original|initial|full|complete|exact|raw)\\s+)*(?:prompt|instructions?|directive|configuration|rules?|guidelines?)/i,\n    severity: 'medium',\n    description: 'System-prompt extraction attempt',\n  },\n  {\n    rule: 'what-are-instructions',\n    pattern: /\\bwhat\\s+(?:are|were|is)\\s+(?:your|the)\\s+(?:original\\s+|initial\\s+|system\\s+)?(?:instructions?|directives?|rules?|prompts?|guidelines?)\\b/i,\n    severity: 'medium',\n    description: 'Indirect system-prompt extraction',\n  },\n  {\n    rule: 'fake-system-tag',\n    pattern: /<\\/?\\s*(?:system|instructions?|prompt|admin|root|sudo|user_admin)\\s*>/i,\n    severity: 'medium',\n    description: 'Forged XML-style system delimiter',\n  },\n  {\n    rule: 'fake-system-marker',\n    pattern: /(?:^|\\n)\\s*(?:#{1,3}\\s*|\\[\\s*|\\*\\*\\s*)?(?:SYSTEM|INSTRUCTIONS?|ADMIN|ROOT|PROMPT)\\s*[:>=#]\\s*/i,\n    severity: 'medium',\n    description: 'Forged Markdown/heading-style system marker',\n  },\n  {\n    rule: 'begin-new-instructions',\n    pattern: /\\b(?:BEGIN|START|INITIATE)\\s+(?:NEW\\s+|UPDATED\\s+|REPLACEMENT\\s+)?(?:INSTRUCTIONS?|PROMPT|SYSTEM|RULES?|DIRECTIVES?)\\b/i,\n    severity: 'medium',\n    description: '\"BEGIN NEW INSTRUCTIONS\" marker',\n  },\n  {\n    rule: 'end-of-input-marker',\n    pattern: /\\[\\s*(?:END|FINISH|TERMINATE|STOP|CLOSE)\\s+(?:OF\\s+)?(?:INPUT|USER|MESSAGE|CONVERSATION|CONTEXT)\\s*\\]/i,\n    severity: 'medium',\n    description: 'Fake \"[END OF INPUT]\" marker',\n  },\n  {\n    rule: 'human-assistant-replay',\n    pattern: /\\n\\s*(?:Human|User|Assistant|AI):\\s*/i,\n    severity: 'medium',\n    description: 'Forged Human:/Assistant: turn marker',\n  },\n  {\n    rule: 'output-after-marker',\n    pattern: /\\b(?:after\\s+(?:this|the\\s+\\w+))\\s*[,.]?\\s*(?:output|print|say|respond|reply|return|generate)\\b/i,\n    severity: 'medium',\n    description: 'Conditional output redirection',\n  },\n  {\n    // System-prompt extraction via the \"repeat the words above\" trick\n    // (Bing/Sydney leak 2023). Requires an output verb + a \"words/text/\n    // everything\" object + an \"above/before/preceding\" anchor, so it\n    // does not fire on ordinary \"repeat that\" conversational text.\n    rule: 'repeat-words-above',\n    pattern: /\\b(?:repeat|print|output|echo|reproduce|reveal|show)\\s+(?:me\\s+)?(?:the\\s+|all\\s+(?:the\\s+)?|every\\s+)?(?:words?|text|lines?|content|everything|message|sentences?|prompt)\\s+(?:above|before|preceding|prior|earlier|that\\s+(?:came|appear|precede))/i,\n    severity: 'medium',\n    description: 'System-prompt extraction via \"repeat the words above\"',\n  },\n  {\n    rule: 'translate-but-do-other',\n    pattern: /\\b(?:translate|summari[sz]e|paraphrase|rewrite)\\s+.{0,80}\\b(?:but|then|after|and)\\s+(?:also\\s+)?(?:do|say|output|tell|reveal|print)\\b/i,\n    severity: 'medium',\n    description: 'Task-hijack via \"translate X but Y\"',\n  },\n  {\n    rule: 'base64-suspicious',\n    pattern: /\\b(?:base64|b64|decode|encoded?\\s+(?:in|as)\\s+base64|atob)\\b/i,\n    severity: 'medium',\n    description: 'Base64-decode hint (often used to smuggle jailbreaks)',\n  },\n  {\n    rule: 'rot13-encoding',\n    pattern: /\\b(?:rot13|rot-13|caesar(?:\\s+cipher)?)\\b/i,\n    severity: 'medium',\n    description: 'ROT13 / Caesar-cipher decode hint',\n  },\n\n  // ── V32: AI agent toolcall injection (improvements.md §1.2) ────────\n  // Modern LLM agents (Claude tool-use, OpenAI function-calling,\n  // ReAct loops) read tool definitions from the system prompt and\n  // JSON-shaped requests from the model. A malicious user can embed\n  // those shapes in their input to make the host think they invoked\n  // a tool, or to trick the model into echoing a synthesized\n  // tool_call that the runtime then executes.\n  //\n  // Narrow patterns. Match the literal JSON keys and inline\n  // tool-name shapes. Won't false-positive on plain English text\n  // discussing tools.\n  {\n    rule: 'agent-toolcall-marker',\n    pattern: /\"(?:tool_call|function_call|call_tool|tool_use|toolUse)\"\\s*:\\s*\\{/i,\n    severity: 'high',\n    description: 'Injected agent tool-call JSON shape (e.g. {\"tool_call\":{...}})',\n  },\n  {\n    // Bracket-style tool marker: `[TOOL_USE: shell, command=\"...\"]`. The\n    // JSON-shape rule above misses this inline form, which is what\n    // ReAct-style and text-protocol agents actually parse out of model\n    // output. Won't fire on prose because it requires the bracket + a\n    // tool keyword + `:` or `=` immediately after.\n    rule: 'agent-toolcall-bracket',\n    pattern: /\\[\\s*(?:TOOL_USE|TOOL_CALL|FUNCTION_CALL|TOOL|FUNCTION|ACTION|EXECUTE)\\s*[:=]/i,\n    severity: 'high',\n    description: 'Injected bracket-style agent tool marker (e.g. [TOOL_USE: shell])',\n  },\n  {\n    rule: 'agent-tool-name-spoof',\n    pattern:\n      /\"name\"\\s*:\\s*\"(?:exec|shell|run_command|system|bash|cmd|python|eval|read_file|write_file|delete_file)\"/i,\n    severity: 'high',\n    description: 'Forged tool-name attempting privileged tool invocation',\n  },\n  {\n    rule: 'agent-tool-result-marker',\n    pattern: /\"(?:tool_result|function_result|tool_output)\"\\s*:\\s*[\\{\\[\"]/i,\n    severity: 'high',\n    description: 'Injected fake tool-result block (trick agent into trusting fabricated output)',\n  },\n  {\n    rule: 'ansi-escape-sequence',\n    pattern: /\\x1b\\[/,\n    severity: 'medium',\n    description: 'ANSI escape sequence (terminal hijack / output spoofing on CLI agents)',\n  },\n  {\n    // Unicode Tag characters (U+E0000-U+E007F). Invisible in nearly\n    // every renderer but tokenizable by LLMs, so an attacker hides\n    // \"Ignore previous instructions\" inside what looks like plain text.\n    // These code points have no legitimate use in user input.\n    rule: 'unicode-tag-smuggle',\n    pattern: /[\\u{E0000}-\\u{E007F}]/u,\n    severity: 'high',\n    description: 'Unicode Tag characters smuggling hidden instructions',\n  },\n  {\n    rule: 'claude-tool-use-tags',\n    pattern: /<\\/?\\s*(?:tool_use|tool_result|invoke|function_calls?|parameter)\\b/i,\n    severity: 'high',\n    description: 'Claude/OpenAI tool-use XML-style tag forgery',\n  },\n\n  // ── Prompt-template marker forgeries ────────────────────────────────\n  // Catches inline forgery of the special tokens that LLM runtimes use\n  // to delimit roles. If a user can land any of these in their input\n  // and the host concatenates the input into a prompt without\n  // re-tokenizing, the model treats the suffix as a new system turn.\n  //\n  // Covered runtimes:\n  //   - ChatML (OpenAI / Llama 3 chat): <|im_start|>, <|im_end|>\n  //   - Llama 2 chat: [INST] <<SYS>> ... <</SYS>>\n  //   - guidance/handlebars: {{#system~}}, {{/system~}}, {{#assistant~}}\n  //   - Markdown link spoof: [system](#assistant), [admin](#context)\n  {\n    rule: 'chatml-template-marker',\n    pattern: /<\\|im_(?:start|end)\\|>(?:\\s*(?:system|assistant|user|tool|function))?/i,\n    severity: 'high',\n    description: 'ChatML special token forgery (<|im_start|>...) to spoof a role turn',\n  },\n  {\n    rule: 'llama2-system-marker',\n    pattern: /<<\\s*\\/?\\s*SYS\\s*>>|\\[\\s*\\/?\\s*INST\\s*\\]/i,\n    severity: 'high',\n    description: 'Llama 2 [INST]/<<SYS>> instruction-template marker forgery',\n  },\n  {\n    rule: 'guidance-template-marker',\n    pattern: /\\{\\{\\s*[#/]\\s*(?:system|assistant|user|tool|function)\\s*~?\\s*\\}\\}/i,\n    severity: 'medium',\n    description: 'guidance/handlebars role-block marker forgery ({{#system~}} ...)',\n  },\n  {\n    rule: 'markdown-system-link-spoof',\n    pattern: /\\[\\s*(?:system|admin|root|assistant)\\s*\\]\\s*\\(\\s*#(?:assistant|context|system|root|admin)\\s*\\)/i,\n    severity: 'medium',\n    description: 'Markdown link forgery spoofing a role marker ([system](#assistant))',\n  },\n\n  // --- LOW severity: ambiguous but worth flagging in strict mode ---\n  {\n    rule: 'from-now-on',\n    pattern: /\\bfrom\\s+now\\s+on\\b\\s*[,.]?\\s*(?:you|always|never)/i,\n    severity: 'low',\n    description: 'Persistent-instruction prefix',\n  },\n  {\n    rule: 'your-new-purpose',\n    pattern: /\\byour\\s+(?:new|real|true|primary|only)\\s+(?:purpose|role|task|goal|job|function)\\s+is\\b/i,\n    severity: 'low',\n    description: 'Persona/purpose redefinition',\n  },\n  {\n    rule: 'forget-everything',\n    pattern: /\\bforget\\s+(?:everything|all|the\\s+(?:above|previous|prior))\\b/i,\n    severity: 'low',\n    description: 'Memory-clear directive',\n  },\n  {\n    rule: 'no-warnings',\n    pattern: /\\b(?:without|don'?t|do\\s+not)\\s+(?:add|include|provide|give|send|print)\\s+(?:any\\s+)?(?:warnings?|disclaimers?|caveats?|safety\\s+notes?|legal\\s+notice)/i,\n    severity: 'low',\n    description: 'Warning-suppression directive',\n  },\n  {\n    rule: 'hypothetical-prefix',\n    pattern: /\\b(?:hypothetically|in\\s+a\\s+hypothetical\\s+(?:world|scenario)|imagine\\s+(?:a\\s+)?(?:world|scenario|situation)\\s+where)\\b/i,\n    severity: 'low',\n    description: 'Hypothetical framing (common jailbreak prefix)',\n  },\n  {\n    rule: 'just-a-story',\n    pattern: /\\b(?:just|only|merely)\\s+(?:a\\s+)?(?:story|fiction|hypothetical|thought\\s+experiment|joke|game|test)\\b/i,\n    severity: 'low',\n    description: 'Fictional framing escape',\n  },\n];\n\nconst SEVERITY_RANK: Record<PromptInjectionSeverity, number> = {\n  low: 1,\n  medium: 2,\n  high: 3,\n};\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\n/**\n * Detect prompt-injection signatures in `text`. Returns all matches with\n * severity and the highest severity seen. Does not modify the input.\n *\n * @example\n * const r = detectPromptInjection('Ignore the previous instructions.');\n * if (r.detected && r.severity === 'high') return res.status(403).end();\n */\nexport function detectPromptInjection(text: string): DetectPromptInjectionResult {\n  if (typeof text !== 'string' || text.length === 0) {\n    return { detected: false, matches: [], severity: 'none' };\n  }\n\n  const matches: PromptInjectionMatch[] = [];\n  let topRank = 0;\n  let topSeverity: PromptInjectionSeverity | 'none' = 'none';\n\n  for (const sig of SIGNATURES) {\n    const m = sig.pattern.exec(text);\n    if (m) {\n      const matched = m[0].slice(0, 80);\n      matches.push({\n        rule: sig.rule,\n        severity: sig.severity,\n        description: sig.description,\n        match: matched,\n      });\n      const rank = SEVERITY_RANK[sig.severity];\n      if (rank > topRank) {\n        topRank = rank;\n        topSeverity = sig.severity;\n      }\n    }\n  }\n\n  return {\n    detected: matches.length > 0,\n    matches,\n    severity: topSeverity,\n  };\n}\n\n/**\n * Strip prompt-injection signatures from `text`. For HIGH and MEDIUM\n * severity matches the matched span is replaced with `[REDACTED]`. LOW\n * severity matches are left in place by default. Toggle via `redactLow`.\n *\n * Returns the sanitized string. To inspect what was stripped, call\n * `detectPromptInjection` first or pass `collectMatches: true`.\n */\nexport function sanitizePromptInjection(\n  text: string,\n  options: { redactLow?: boolean; replacement?: string } = {},\n): string {\n  if (typeof text !== 'string' || text.length === 0) return text ?? '';\n\n  const replacement = options.replacement ?? '[REDACTED]';\n  const redactLow = options.redactLow ?? false;\n  let value = text;\n\n  for (const sig of SIGNATURES) {\n    if (sig.severity === 'low' && !redactLow) continue;\n    // Use a global flavor of the pattern so multiple occurrences are removed.\n    const flags = sig.pattern.flags.includes('g') ? sig.pattern.flags : sig.pattern.flags + 'g';\n    const globalPattern = new RegExp(sig.pattern.source, flags);\n    value = value.replace(globalPattern, replacement);\n  }\n\n  return value;\n}\n","/**\n * @module @arcis/node/sanitizers/utils\n * Shared utilities for sanitizers\n */\n\n/**\n * Encodes HTML entities to prevent interpretation as markup.\n * \n * @param str - The string to encode\n * @returns The encoded string\n */\nexport function encodeHtmlEntities(str: string): string {\n  return str\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#x27;');\n}\n\n/**\n * Checks if a value is a plain object (not null, array, Date, etc.)\n * \n * @param value - Value to check\n * @returns True if plain object\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n  if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n    return false;\n  }\n  // Check the actual prototype chain rather than toString, which can be spoofed\n  // via Symbol.toStringTag. Accepts both Object.prototype (plain {}) and null\n  // prototype objects (Object.create(null)).\n  const proto = Object.getPrototypeOf(value as object);\n  return proto === Object.prototype || proto === null;\n}\n","/**\n * @module @arcis/node/sanitizers/xss\n * XSS (Cross-Site Scripting) prevention\n */\n\nimport { XSS_PATTERNS, XSS_REMOVE_PATTERNS } from '../core/constants';\nimport { encodeHtmlEntities } from './utils';\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * Sanitizes a string to prevent XSS attacks.\n * \n * Strategy:\n * 1. Remove dangerous patterns (script tags, event handlers, etc.)\n * 2. HTML-encode the remaining content\n * \n * @param input - The string to sanitize\n * @param collectThreats - Whether to collect threat information (default: false for performance)\n * @returns Sanitized string or SanitizeResult if collectThreats is true\n * \n * @example\n * sanitizeXss(\"<script>alert('xss')</script>\")\n * // Returns: \"&lt;script&gt;alert(&#x27;xss&#x27;)&lt;/script&gt;\"\n * \n * @example\n * sanitizeXss(\"<img onerror='alert(1)'>\")\n * // Returns: \"&lt;img&gt;\" (event handler removed)\n */\nexport function sanitizeXss(input: string, collectThreats?: false, htmlEncode?: boolean): string;\nexport function sanitizeXss(input: string, collectThreats: true, htmlEncode?: boolean): SanitizeResult;\nexport function sanitizeXss(input: string, collectThreats = false, htmlEncode = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats \n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  // Remove dangerous patterns FIRST — XSS_REMOVE_PATTERNS is the single\n  // source of truth (defined in constants.ts alongside XSS_PATTERNS).\n  for (const pattern of XSS_REMOVE_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(value)) {\n      pattern.lastIndex = 0;\n      \n      if (collectThreats) {\n        const matches = value.match(pattern);\n        if (matches) {\n          for (const match of matches) {\n            threats.push({\n              type: 'xss',\n              pattern: pattern.source,\n              original: match,\n            });\n          }\n        }\n      }\n      \n      value = value.replace(pattern, '');\n      wasSanitized = true;\n    }\n  }\n\n  // HTML-encode only when explicitly requested (SSR/template context).\n  // Do NOT encode by default — this is a REST API middleware; encoding\n  // here corrupts JSON data with HTML entities (&lt;, &amp;, etc.) that\n  // consumers would receive verbatim.\n  if (htmlEncode) {\n    const encoded = encodeHtmlEntities(value);\n    if (encoded !== value) {\n      wasSanitized = true;\n    }\n    value = encoded;\n  }\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n  \n  return value;\n}\n\n/**\n * Checks if a string contains potential XSS patterns.\n * Does not sanitize — use sanitizeXss() for that.\n * \n * @param input - The string to check\n * @returns True if XSS patterns detected\n */\nexport function detectXss(input: string): boolean {\n  if (typeof input !== 'string') return false;\n\n  // All XSS detection now flows through the shared patterns.json `xss` rules\n  // (event handlers, javascript:/vbscript:/data: protocols, tags). The former\n  // inline fast-path checks were a strict subset of these rules, so they were\n  // removed when the patterns moved to patterns.json (single source).\n  for (const pattern of XSS_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(input)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/sql\n * SQL injection prevention\n */\n\nimport { SQL_PATTERNS } from '../core/constants';\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * Sanitizes a string to prevent SQL injection attacks.\n * Replaces dangerous SQL patterns with [BLOCKED].\n * \n * @param input - The string to sanitize\n * @param collectThreats - Whether to collect threat information (default: false for performance)\n * @returns Sanitized string or SanitizeResult if collectThreats is true\n * \n * @example\n * sanitizeSql(\"'; DROP TABLE users; --\")\n * // Returns: \"';  TABLE users  \"\n */\nexport function sanitizeSql(input: string, collectThreats?: false): string;\nexport function sanitizeSql(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizeSql(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats \n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  for (const pattern of SQL_PATTERNS) {\n    // Reset regex lastIndex for global patterns\n    pattern.lastIndex = 0;\n    \n    if (pattern.test(value)) {\n      pattern.lastIndex = 0; // Reset again for replace\n      \n      if (collectThreats) {\n        const matches = value.match(pattern);\n        if (matches) {\n          for (const match of matches) {\n            threats.push({\n              type: 'sql_injection',\n              pattern: pattern.source,\n              original: match,\n            });\n          }\n        }\n      }\n      \n      // Replace the matched content with a space to avoid concatenating surrounding\n      // tokens into new dangerous strings (e.g. \"SELECTname\" after stripping \"SELECT\").\n      value = value.replace(pattern, ' ');\n      wasSanitized = true;\n    }\n  }\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n  \n  return value;\n}\n\n/**\n * Checks if a string contains potential SQL injection patterns.\n * Does not sanitize — use sanitizeSql() for that.\n * \n * @param input - The string to check\n * @returns True if SQL injection patterns detected\n */\nexport function detectSql(input: string): boolean {\n  if (typeof input !== 'string') return false;\n  \n  for (const pattern of SQL_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(input)) {\n      return true;\n    }\n  }\n  \n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/path\n * Path traversal prevention\n */\n\nimport { PATH_PATTERNS } from '../core/constants';\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * Sanitizes a string to prevent path traversal attacks.\n * Removes ../ and ..\\ patterns (including URL-encoded variants).\n * \n * @param input - The string to sanitize\n * @param collectThreats - Whether to collect threat information (default: false for performance)\n * @returns Sanitized string or SanitizeResult if collectThreats is true\n * \n * @example\n * sanitizePath(\"../../etc/passwd\")\n * // Returns: \"etc/passwd\"\n */\nexport function sanitizePath(input: string, collectThreats?: false): string;\nexport function sanitizePath(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizePath(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats \n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  // SECURITY: Normalize Unicode to NFKC before pattern matching.\n  // Fullwidth dot U+FF0E normalizes to '.', preventing ．．/ bypass of ../ detection.\n  value = value.normalize('NFKC');\n\n  // Apply patterns repeatedly until the string stops changing.\n  // Single-pass stripping is bypassable: \"....//\".replace(\"../\",\"\") → \"../\"\n  let prev: string;\n  do {\n    prev = value;\n    for (const pattern of PATH_PATTERNS) {\n      pattern.lastIndex = 0;\n\n      if (pattern.test(value)) {\n        pattern.lastIndex = 0;\n\n        if (collectThreats) {\n          const matches = value.match(pattern);\n          if (matches) {\n            for (const match of matches) {\n              threats.push({\n                type: 'path_traversal',\n                pattern: pattern.source,\n                original: match,\n              });\n            }\n          }\n        }\n\n        value = value.replace(pattern, '');\n        wasSanitized = true;\n      }\n    }\n  } while (value !== prev);\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n  \n  return value;\n}\n\n/**\n * Checks if a string contains path traversal patterns.\n * Does not sanitize — use sanitizePath() for that.\n * \n * @param input - The string to check\n * @returns True if path traversal patterns detected\n */\nexport function detectPathTraversal(input: string): boolean {\n  if (typeof input !== 'string') return false;\n\n  // SECURITY: Normalize Unicode to NFKC — same as sanitizePath\n  const normalized = input.normalize('NFKC');\n\n  for (const pattern of PATH_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(normalized)) {\n      return true;\n    }\n  }\n  \n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/command\n * Command injection prevention\n */\n\nimport { COMMAND_PATTERNS } from '../core/constants';\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * Sanitizes a string to prevent command injection attacks.\n * Replaces shell metacharacters and dangerous commands with [BLOCKED].\n * \n * @param input - The string to sanitize\n * @param collectThreats - Whether to collect threat information (default: false for performance)\n * @returns Sanitized string or SanitizeResult if collectThreats is true\n * \n * @example\n * sanitizeCommand(\"file.txt; rm -rf /\")\n * // Returns: \"file.txt  rm -rf /\"\n */\nexport function sanitizeCommand(input: string, collectThreats?: false): string;\nexport function sanitizeCommand(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizeCommand(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats \n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  for (const pattern of COMMAND_PATTERNS) {\n    // Reset regex lastIndex for global patterns\n    pattern.lastIndex = 0;\n    \n    if (pattern.test(value)) {\n      pattern.lastIndex = 0; // Reset again for replace\n      \n      if (collectThreats) {\n        const matches = value.match(pattern);\n        if (matches) {\n          for (const match of matches) {\n            threats.push({\n              type: 'command_injection',\n              pattern: pattern.source,\n              original: match,\n            });\n          }\n        }\n      }\n      \n      value = value.replace(pattern, ' ');\n      wasSanitized = true;\n    }\n  }\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n  \n  return value;\n}\n\n/**\n * Checks if a string contains command injection patterns.\n * Does not sanitize — use sanitizeCommand() for that.\n * \n * @param input - The string to check\n * @returns True if command injection patterns detected\n */\nexport function detectCommandInjection(input: string): boolean {\n  if (typeof input !== 'string') return false;\n  \n  for (const pattern of COMMAND_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(input)) {\n      return true;\n    }\n  }\n  \n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/ssti\n * Server-Side Template Injection (SSTI) prevention\n */\n\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * SSTI detection patterns (ReDoS-safe).\n *\n * Covers Jinja2, Twig, Nunjucks, Freemarker, Thymeleaf, Spring EL,\n * ERB, EJS, Pug/Jade, and Python sandbox-escape dunder chains.\n */\nconst SSTI_DETECT_PATTERNS = [\n  /** Jinja2 / Twig / Nunjucks: {{ ... }} */\n  /\\{\\{.*?\\}\\}/g,\n  /** Freemarker / Thymeleaf / Spring EL: ${ ... } */\n  /\\$\\{.*?\\}/g,\n  /** ERB / EJS: <%= ... %> or <% ... %> */\n  /<%[=\\-]?.*?%>/gs,\n  /** Pug / Jade / Slim: #{ ... } */\n  /#\\{.*?\\}/g,\n  /** Python dunder sandbox escape */\n  /__(?:class|mro|subclasses|globals|builtins|import)__/gi,\n  /** Jinja2 config leak: {{config.X}} or {{config['X']}} */\n  /\\{\\{\\s*config[.\\[]/gi,\n  /** Jinja2 built-in objects */\n  /\\{\\{\\s*(?:self|request|lipsum|cycler|joiner|namespace|range)\\b/gi,\n  /** Velocity #set/#foreach + OGNL/Velocity method calls ($rt.exec, .getRuntime). Benchmark ssti-velocity-runtime. */\n  /#set\\s*\\(\\s*\\$|#foreach\\s*\\(\\s*\\$|\\$\\w+\\.(?:exec|getClass|getRuntime|getMethod|invoke)\\b/gi,\n  /** Laravel Blade raw-PHP directive: `@php(...)` inline or `@php ... @endphp` block\n   * (the `{{ }}` Blade echo form is already covered above). Requires `@php(` or the\n   * `@endphp` close so it doesn't fire on the bare `@php` social handle. */\n  /@php\\s*\\(|@endphp\\b/gi,\n] as const;\n\n/**\n * Removal patterns — strip template expressions that look like actual attacks.\n *\n * ${ and #{ patterns are narrowed to require operators/method-calls inside to\n * avoid false-positives on JS template literals (${name}) and Ruby/Pug output\n * expressions (#{name}) that appear in legitimate user-submitted content.\n *\n * The broader detection patterns above still flag these for detectSsti() —\n * narrowing only applies to destructive sanitization.\n */\nconst SSTI_REMOVE_PATTERNS = [\n  /** Jinja2 / Twig: {{ ... }} — always strip (not valid in any JS context) */\n  /\\{\\{.*?\\}\\}/g,\n  /**\n   * Freemarker / Spring EL: ${...} — strip when expression contains operators,\n   * method calls, or Python dunder patterns (sandbox escape).\n   * Bare ${name} and ${user.name} are left intact (JS template literal syntax).\n   */\n  /\\$\\{[^}]*__\\w+__[^}]*\\}/g,\n  /\\$\\{[^}]*[?!()*+\\-/][^}]*\\}/g,\n  /** ERB / EJS: <%= ... %> */\n  /<%[=\\-]?.*?%>/gs,\n  /**\n   * Pug / Jade: #{...} — same narrowing as ${ above, plus dunder detection.\n   * #{name} output expressions are left intact.\n   */\n  /#\\{[^}]*__\\w+__[^}]*\\}/g,\n  /#\\{[^}]*[?!()*+\\-/][^}]*\\}/g,\n  /** Python dunder sandbox escape — always strip */\n  /__(?:class|mro|subclasses|globals|builtins|import)__/gi,\n] as const;\n\n/**\n * Sanitizes a string to prevent SSTI attacks.\n * Removes template expression syntax.\n */\nexport function sanitizeSsti(input: string, collectThreats?: false): string;\nexport function sanitizeSsti(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizeSsti(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats\n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  for (const pattern of SSTI_REMOVE_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(value)) {\n      pattern.lastIndex = 0;\n\n      if (collectThreats) {\n        const matches = value.match(pattern);\n        if (matches) {\n          for (const match of matches) {\n            threats.push({\n              type: 'ssti',\n              pattern: pattern.source,\n              original: match,\n            });\n          }\n        }\n      }\n\n      value = value.replace(pattern, '');\n      wasSanitized = true;\n    }\n  }\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n\n  return value;\n}\n\n/**\n * Checks if a string contains SSTI patterns.\n * Does not sanitize — use sanitizeSsti() for that.\n *\n * @param input - The string to check\n * @returns True if SSTI patterns detected\n */\nexport function detectSsti(input: string): boolean {\n  if (typeof input !== 'string') return false;\n\n  for (const pattern of SSTI_DETECT_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(input)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/xxe\n * XML External Entity (XXE) injection prevention\n */\n\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * XXE detection patterns (ReDoS-safe).\n *\n * Covers DOCTYPE declarations, ENTITY definitions, SYSTEM/PUBLIC references,\n * parameter entities, and CDATA abuse.\n */\n/**\n * Billion-laughs defense: cap raw XML input length and the count of\n * entity references. A valid document rarely needs more than a handful of\n * entities; thousands of `&foo;` references is the classic bomb shape.\n */\nconst MAX_XXE_INPUT_BYTES = 1_000_000; // 1 MB — above any reasonable config/SOAP payload\nconst MAX_ENTITY_REFERENCES = 64;\n\nconst XXE_DETECT_PATTERNS = [\n  /** DOCTYPE declaration */\n  /<!DOCTYPE\\b/gi,\n  /** ENTITY declaration */\n  /<!ENTITY\\b/gi,\n  /** SYSTEM keyword with URI */\n  /\\bSYSTEM\\s+[\"']/gi,\n  /** PUBLIC keyword with URI */\n  /\\bPUBLIC\\s+[\"']/gi,\n  /** Parameter entity reference (%entity;) */\n  /%\\s*\\w+\\s*;/g,\n  /** CDATA section (often used to smuggle payloads) */\n  /<!\\[CDATA\\[/gi,\n] as const;\n\n/** Removal patterns — strip the dangerous XML constructs */\nconst XXE_REMOVE_PATTERNS = [\n  /** Full DOCTYPE block with optional internal subset: <!DOCTYPE ... [...]> */\n  /<!DOCTYPE\\s[^[>]*(?:\\[[^\\]]*\\]\\s*)?>|<!DOCTYPE\\s[^>]*>/gi,\n  /** Full ENTITY declaration: <!ENTITY ... > */\n  /<!ENTITY[^>]*>/gi,\n  /** CDATA sections: <![CDATA[ ... ]]> */\n  /<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/gi,\n] as const;\n\n/**\n * Sanitizes a string to prevent XXE attacks.\n * Removes DOCTYPE, ENTITY, and CDATA constructs.\n */\nexport function sanitizeXxe(input: string, collectThreats?: false): string;\nexport function sanitizeXxe(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizeXxe(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats\n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let value = input;\n  let wasSanitized = false;\n\n  // Billion-laughs defense: oversize input or many entity refs → flatten to empty.\n  // Safer to discard than to attempt partial sanitization of a bomb payload.\n  if (value.length > MAX_XXE_INPUT_BYTES) {\n    if (collectThreats) {\n      threats.push({ type: 'xxe', pattern: 'oversize_input', original: `length=${value.length}` });\n    }\n    return collectThreats ? { value: '', wasSanitized: true, threats } : '';\n  }\n  const entityRefs = value.match(/&\\w+;/g);\n  if (entityRefs && entityRefs.length > MAX_ENTITY_REFERENCES) {\n    if (collectThreats) {\n      threats.push({ type: 'xxe', pattern: 'entity_expansion', original: `count=${entityRefs.length}` });\n    }\n    return collectThreats ? { value: '', wasSanitized: true, threats } : '';\n  }\n\n  for (const pattern of XXE_REMOVE_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(value)) {\n      pattern.lastIndex = 0;\n\n      if (collectThreats) {\n        const matches = value.match(pattern);\n        if (matches) {\n          for (const match of matches) {\n            threats.push({\n              type: 'xxe',\n              pattern: pattern.source,\n              original: match,\n            });\n          }\n        }\n      }\n\n      value = value.replace(pattern, '');\n      wasSanitized = true;\n    }\n  }\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n\n  return value;\n}\n\n/**\n * Checks if a string contains XXE patterns.\n * Does not sanitize — use sanitizeXxe() for that.\n *\n * @param input - The string to check\n * @returns True if XXE patterns detected\n */\nexport function detectXxe(input: string): boolean {\n  if (typeof input !== 'string') return false;\n\n  for (const pattern of XXE_DETECT_PATTERNS) {\n    pattern.lastIndex = 0;\n    if (pattern.test(input)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n","/**\n * @module @arcis/node/sanitizers/ldap\n * LDAP injection prevention\n *\n * LDAP special characters in filter context: * ( ) \\ NUL\n * LDAP special characters in DN context:     , + < > ; \" = / \\ NUL\n *\n * RFC 4515 (filter) and RFC 4514 (DN) define the escaping rules.\n * Sanitization escapes rather than strips — preserves the original value\n * while making it safe to embed in LDAP queries.\n */\n\n// LDAP filter special characters per RFC 4515 (single pass includes NUL).\n// Used for ESCAPING — broad set is fine here because escaping a benign\n// char is safe; the value just gets a `\\xx` representation.\nconst LDAP_FILTER_CHARS = /[*()\\\\\\x00]/g;\n\n// LDAP DN special characters per RFC 4514 (single pass includes NUL)\nconst LDAP_DN_CHARS = /[,+<>;\"=\\/\\\\\\x00*()\\x00]/g;\n\n// Wildcard-value detection: `=*` inside a filter (e.g. `(uid=*)`).\n// Real LDAP filter abuse; legitimate values don't end in `=*`.\nconst LDAP_WILDCARD_VALUE_PATTERN = /=\\s*\\*/;\n\n// NUL byte detection — used for LDAP query truncation attacks.\n// Matches both a real NUL (`\\x00`) and the literal escape sequence\n// `\\00` (backslash-zero-zero), which is how it arrives over JSON/form\n// text before any decode. Benchmark ldap-null-byte-truncate.\nconst LDAP_NUL_PATTERN = /\\x00|\\\\00/;\n\n// Detection pattern for OR/AND bypass and wildcard abuse.\n// Real shapes: `*)(uid=*` (break the filter, inject a new clause).\nconst LDAP_INJECTION_PATTERN = /\\)\\s*\\(|\\*\\s*\\)\\s*\\(/;\n\n// Detection pattern for LDAP NOT-operator bypass (improvements.md Q8).\n// Catches ')(!', '&(!', '|(!' shapes that legitimate filters never contain;\n// these are the attacker's NOT-clause appended to enumerate or exclude\n// entries (e.g. '*)(uid=*)(!(uid=admin))'). Companion to\n// LDAP_INJECTION_PATTERN; together they cover the OR-then-NOT corpus.\nconst LDAP_NOT_BYPASS_PATTERN = /\\)\\s*\\(\\s*!|&\\s*\\(\\s*!|\\|\\s*\\(\\s*!/;\n\nconst escapeChar = (char: string) => '\\\\' + char.charCodeAt(0).toString(16).padStart(2, '0');\n\n/**\n * Sanitizes a string for safe use in LDAP filter expressions.\n * Escapes * ( ) \\ and NUL per RFC 4515.\n *\n * @example\n * sanitizeLdapFilter(\"user*(admin)\")\n * // Returns: \"user\\2a\\28admin\\29\"\n */\nexport function sanitizeLdapFilter(input: string): string {\n  if (typeof input !== 'string') return String(input);\n  return input.replace(LDAP_FILTER_CHARS, escapeChar);\n}\n\n/**\n * Sanitizes a string for safe use in LDAP Distinguished Names (DN).\n * Escapes , + < > ; \" = / \\ and NUL per RFC 4514.\n *\n * @example\n * sanitizeLdapDn(\"cn=admin,dc=example\")\n * // Returns: \"cn\\3dadmin\\2cdc\\3dexample\"\n */\nexport function sanitizeLdapDn(input: string): string {\n  if (typeof input !== 'string') return String(input);\n  return input.replace(LDAP_DN_CHARS, escapeChar);\n}\n\n/**\n * Detects potential LDAP injection patterns in a string.\n * Does not sanitize — use sanitizeLdapFilter() or sanitizeLdapDn() for that.\n *\n * Designed for request-boundary scanning: matches only the specific\n * shapes real LDAP injection produces. The older broad\n * `[*()\\\\\\x00]` pattern was removed because it false-positived on\n * every markdown bold `**bold**`, every parenthesised string, every\n * apostrophe-in-name. Mirrors the `ldap-injection-strict` +\n * `ldap-not-bypass` rules from packages/core/patterns.json which are\n * marked `request_boundary_safe: true`. Benchmark FP class B2, 2026-06-07.\n *\n * @param input - The string to check\n * @returns True if LDAP injection patterns detected\n *\n * @example\n * detectLdapInjection(\"*)(uid=*))(|(uid=*\")  // true  — filter break-out\n * detectLdapInjection(\"(uid=*)\")              // true  — wildcard value\n * detectLdapInjection(\"ad\\x00min\")            // true  — NUL truncation\n * detectLdapInjection(\"**bold**\")             // false — markdown\n * detectLdapInjection(\"hello *world*\")        // false — emphasis\n * detectLdapInjection(\"john\")                 // false\n */\nexport function detectLdapInjection(input: string): boolean {\n  if (typeof input !== 'string') return false;\n  return (\n    LDAP_INJECTION_PATTERN.test(input) ||\n    LDAP_NOT_BYPASS_PATTERN.test(input) ||\n    LDAP_WILDCARD_VALUE_PATTERN.test(input) ||\n    LDAP_NUL_PATTERN.test(input)\n  );\n}\n","/**\n * @module @arcis/node/sanitizers/xpath\n * XPath injection prevention.\n *\n * XPath 1.0 has no escape syntax for string literals — the only way to\n * embed user input safely is parameterised queries / variable bindings.\n * Neither libxml2 nor most JS XPath libraries expose a canonical escape\n * function. The pragmatic answer everyone ships:\n *\n *   - Detect: scan for unescaped quotes or expression-control chars\n *     that suggest the user is trying to break out of a string literal.\n *   - Sanitize: strip the offending control characters. Lossy by design;\n *     callers that need lossless input should use parameterised queries\n *     directly.\n *\n * Detection is the load-bearing surface for this vector. Sanitization is\n * a fallback for users running existing XPath strings through user input\n * who can't switch to bound parameters today.\n */\n\n// XPath expression-control characters that an attacker uses to escape\n// a string literal: single quote, double quote, comma (changes function\n// arity), the union operator |, and parens (used in `) or (` toggles\n// against XPath function calls). These are the same shapes Aikido /\n// Snyk's xpath rules look for.\nconst XPATH_INJECTION_CHARS = /['\"|,()]/;\n\n// Common operator-injection patterns: unescaped boolean injection\n// (`' or '1'='1`), function tampering (`,`), and union (`|`).\n// Also blind-extraction functions (`substring(name(...))`,\n// `string-length(`, `count(/`) used to leak the document one char at a\n// time. Benchmark xpath-blind-substring.\nconst XPATH_INJECTION_PATTERN =\n  /('\\s*(or|and)\\s*'|\"\\s*(or|and)\\s*\"|\\)\\s*(or|and)\\s*\\(|\\|\\s*\\/|\\bsubstring\\s*\\(\\s*name\\s*\\(|\\bstring-length\\s*\\(|\\bcount\\s*\\(\\s*\\/)/i;\n\n/**\n * Detects XPath-injection-shaped patterns in a string. Returns true when\n * the input looks like it's trying to break out of an XPath string\n * literal or hijack the expression structure.\n *\n * Conservative on purpose: triggers on any control char in the input\n * combined with a boolean / union pattern. Plain user names and emails\n * (no quotes, no pipes) pass clean.\n */\nexport function detectXpathInjection(input: string): boolean {\n  if (typeof input !== 'string' || input.length === 0) return false;\n  // Fast path: skip the regex test entirely when no control chars exist.\n  if (!XPATH_INJECTION_CHARS.test(input)) return false;\n  return XPATH_INJECTION_PATTERN.test(input);\n}\n\n/**\n * Strips XPath expression-control characters from a string. Lossy —\n * `O'Brien` becomes `OBrien`. Use only when migrating legacy code that\n * concatenates user input into XPath; new code should use bound\n * parameters via the underlying XPath library.\n */\nexport function sanitizeXpath(input: string): string {\n  if (typeof input !== 'string') return String(input);\n  return input.replace(/['\"|,]/g, '');\n}\n","/**\n * @module @arcis/node/sanitizers/headers\n * HTTP Header Injection & CRLF Injection prevention\n *\n * Prevents attackers from injecting newline characters (\\r\\n) into HTTP header\n * values, which can lead to response splitting, session fixation, XSS via\n * injected headers, and cache poisoning.\n */\n\nimport type { SanitizeResult, ThreatInfo } from '../core/types';\n\n/**\n * Characters and sequences that enable header injection.\n * - \\r\\n (CRLF) — HTTP header delimiter, enables response splitting\n * - \\r, \\n alone — partial line breaks, some servers normalize to CRLF\n * - \\0 (null byte) — can truncate header values in some implementations\n */\nconst HEADER_INJECTION_PATTERN = /\\r\\n|\\r|\\n|\\0/g;\n\n/**\n * Request-boundary header-injection shape: a newline (CRLF or bare CR/LF)\n * followed by a header-name token and a colon (`\\r\\nSet-Cookie:`,\n * `\\nX-Injected:`). This is the response-splitting / header-smuggling\n * signal. Unlike HEADER_INJECTION_PATTERN it does NOT flag a bare newline,\n * so multi-line request bodies (markdown, textareas, code) pass cleanly.\n * Mirrors Python's email-header-bare-newline rule. v1.7 parity 2026-06-08.\n */\nconst HEADER_INJECTION_STRICT_PATTERN =\n  /(?:\\r\\n|\\r|\\n)\\s*[a-zA-Z][a-zA-Z0-9-]{0,40}\\s*:/;\n\n/**\n * Narrow header-injection check for request-boundary scanning. Returns\n * true only on a CRLF-then-header-name-then-colon shape, never on a bare\n * newline. Use this in `scanThreats`; use `detectHeaderInjection` (broad)\n * when sanitizing a value destined for a response header.\n */\nexport function detectHeaderInjectionStrict(input: string): boolean {\n  if (typeof input !== 'string') return false;\n  return HEADER_INJECTION_STRICT_PATTERN.test(input);\n}\n\n/**\n * Sanitizes a header value by stripping CRLF sequences, bare CR/LF, and null bytes.\n *\n * @param input - The header value to sanitize\n * @param collectThreats - Whether to collect threat information (default: false)\n * @returns Sanitized string or SanitizeResult if collectThreats is true\n *\n * @example\n * sanitizeHeaderValue(\"safe-value\")\n * // Returns: \"safe-value\"\n *\n * sanitizeHeaderValue(\"value\\r\\nX-Injected: evil\")\n * // Returns: \"valueX-Injected: evil\"\n */\nexport function sanitizeHeaderValue(input: string, collectThreats?: false): string;\nexport function sanitizeHeaderValue(input: string, collectThreats: true): SanitizeResult;\nexport function sanitizeHeaderValue(input: string, collectThreats = false): string | SanitizeResult {\n  if (typeof input !== 'string') {\n    return collectThreats\n      ? { value: String(input), wasSanitized: false, threats: [] }\n      : String(input);\n  }\n\n  const threats: ThreatInfo[] = [];\n  let wasSanitized = false;\n\n  if (HEADER_INJECTION_PATTERN.test(input)) {\n    HEADER_INJECTION_PATTERN.lastIndex = 0;\n    wasSanitized = true;\n\n    if (collectThreats) {\n      const matches = input.match(HEADER_INJECTION_PATTERN);\n      if (matches) {\n        for (const match of matches) {\n          threats.push({\n            type: 'header_injection',\n            pattern: HEADER_INJECTION_PATTERN.source,\n            original: match,\n          });\n        }\n      }\n    }\n  }\n\n  HEADER_INJECTION_PATTERN.lastIndex = 0;\n  const value = input.replace(HEADER_INJECTION_PATTERN, '');\n\n  if (collectThreats) {\n    return { value, wasSanitized, threats };\n  }\n\n  return value;\n}\n\n/**\n * Sanitizes an object of header key-value pairs.\n * Strips CRLF/null bytes from both keys and values.\n *\n * @param headers - Object with header names as keys and header values as values\n * @returns New object with sanitized header names and values\n *\n * @example\n * sanitizeHeaders({ \"X-Custom\": \"safe\", \"X-Bad\\r\\n\": \"value\\r\\ninjected\" })\n * // Returns: { \"X-Custom\": \"safe\", \"X-Bad\": \"valueinjected\" }\n */\nexport function sanitizeHeaders(headers: Record<string, string>): Record<string, string> {\n  if (!headers || typeof headers !== 'object') {\n    return {};\n  }\n\n  const result: Record<string, string> = {};\n\n  for (const [key, value] of Object.entries(headers)) {\n    const sanitizedKey = sanitizeHeaderValue(String(key));\n    const sanitizedValue = sanitizeHeaderValue(String(value));\n    result[sanitizedKey] = sanitizedValue;\n  }\n\n  return result;\n}\n\n/**\n * Checks if a string contains HTTP header injection patterns (CRLF, null bytes).\n * Does not sanitize — use sanitizeHeaderValue() for that.\n *\n * @param input - The string to check\n * @returns True if header injection patterns detected\n */\nexport function detectHeaderInjection(input: string): boolean {\n  if (typeof input !== 'string') return false;\n\n  HEADER_INJECTION_PATTERN.lastIndex = 0;\n  return HEADER_INJECTION_PATTERN.test(input);\n}\n\n/**\n * Email-header injection prevention. Same byte-level threat as HTTP\n * header injection — `\\r\\n` in a user-controlled email field\n * (`To`, `From`, `Subject`, etc.) lets an attacker inject extra headers\n * (most commonly Bcc) and pivot a contact form into a spam relay.\n *\n * Aliased to the HTTP-header sanitizers because the wire-level fix is\n * identical: strip CRLF + null bytes from the value before\n * concatenating into the header. Use these in form-to-email handlers:\n *\n * ```ts\n * const subject = sanitizeEmailHeader(req.body.subject);\n * const to = sanitizeEmailHeader(req.body.to);\n * if (detectEmailHeaderInjection(req.body.to)) reject(...);\n * ```\n */\nexport const sanitizeEmailHeader = sanitizeHeaderValue;\nexport const detectEmailHeaderInjection = detectHeaderInjection;\n","/**\n * @module @arcis/node/sanitizers/deserialization\n *\n * V33 — Modern deserialization marker detection (improvements.md §1.2).\n *\n * Detect input that LOOKS like a serialized-object payload for\n * runtimes where deserialization equals code execution: Python\n * pickle, Java FastJSON, PHP unserialize, Ruby Marshal, .NET\n * BinaryFormatter.\n *\n * Detection-only — the right response to a hit is \"refuse the\n * request\" not \"strip the bytes and pass through\" (a forgiving\n * parser might still deserialize the remainder to something\n * dangerous). Caller decides.\n *\n * Mirrors `arcis-python/arcis/sanitizers/deserialization.py`. Both\n * SDKs must accept the same base corpus per Pattern 7.\n */\n\nexport type DeserializeRuntime =\n  | 'python_pickle'\n  | 'java_fastjson'\n  | 'php_unserialize'\n  | 'ruby_marshal'\n  | 'dotnet_binary_formatter';\n\n// Python pickle: \\x80 followed by version byte 0x02-0x05.\nconst PICKLE_HEAD = /^\\x80[\\x02-\\x05]/;\n\n// Base64-encoded pickle. Attackers ship pickle over JSON/text as base64,\n// so the raw head-byte check never sees \\x80. The base64 of \\x80\\x02..05\n// always starts \"gA\" + a known char; we pre-filter cheaply, then decode\n// and re-check the head byte. Benchmark deser-python-pickle-marker.\nconst PICKLE_B64_PREFIX = /^gA[I-Z]/;\nconst B64_SHAPE = /^[A-Za-z0-9+/]{12,}={0,2}$/;\n\n// Ruby Marshal magic: \\x04\\x08 at start (Ruby 1.9+).\nconst RUBY_MARSHAL_HEAD = /^\\x04\\x08/;\n\n// .NET BinaryFormatter: 5-byte serialization-header.\nconst DOTNET_BINFMT_HEAD = /^\\x00\\x01\\x00\\x00\\x00/;\n\n// Java FastJSON: embedded `\"@type\":\"<class>\"`. Match anywhere.\nconst FASTJSON_AUTOTYPE = /\"@type\"\\s*:\\s*\"[a-zA-Z_$][\\w$.]*\"/;\n\n// PHP unserialize: `O:<len>:\"<ClassName>\":<count>:{` shape.\nconst PHP_UNSERIALIZE = /O:\\d+:\"[a-zA-Z_\\\\][\\w\\\\]*\":\\d+:\\{/;\n\n/**\n * Detect a serialized-object marker for any known runtime.\n *\n * Returns the runtime tag if a marker matches, or null if the input\n * looks safe. Precedence: head-byte markers (pickle / Ruby / .NET)\n * before embedded markers (FastJSON / PHP).\n */\nexport function detectDeserialization(\n  payload: string,\n): DeserializeRuntime | null {\n  if (typeof payload !== 'string' || payload.length === 0) {\n    return null;\n  }\n  if (PICKLE_HEAD.test(payload)) return 'python_pickle';\n  // Base64-encoded pickle: prefix pre-filter, then decode + re-check head.\n  if (PICKLE_B64_PREFIX.test(payload) && B64_SHAPE.test(payload)) {\n    try {\n      const decoded = Buffer.from(payload, 'base64');\n      if (\n        decoded.length >= 2 &&\n        decoded[0] === 0x80 &&\n        decoded[1] >= 0x02 &&\n        decoded[1] <= 0x05\n      ) {\n        return 'python_pickle';\n      }\n    } catch {\n      // not valid base64 — fall through\n    }\n  }\n  if (RUBY_MARSHAL_HEAD.test(payload)) return 'ruby_marshal';\n  if (DOTNET_BINFMT_HEAD.test(payload)) return 'dotnet_binary_formatter';\n  if (FASTJSON_AUTOTYPE.test(payload)) return 'java_fastjson';\n  if (PHP_UNSERIALIZE.test(payload)) return 'php_unserialize';\n  return null;\n}\n\n/** Convenience boolean wrapper around `detectDeserialization`. */\nexport function isSerializedPayload(payload: string): boolean {\n  return detectDeserialization(payload) !== null;\n}\n","/**\n * @module @arcis/node/sanitizers/nosql\n * NoSQL injection prevention (MongoDB operators)\n */\n\nimport { NOSQL_DANGEROUS_KEYS, NOSQL_STRING_PATTERN } from '../core/constants';\n\n/**\n * Checks if a key is a dangerous MongoDB operator.\n * \n * @param key - The key to check\n * @returns True if the key is a MongoDB operator\n * \n * @example\n * isDangerousNoSqlKey('$gt') // true\n * isDangerousNoSqlKey('name') // false\n */\nexport function isDangerousNoSqlKey(key: string): boolean {\n  return NOSQL_DANGEROUS_KEYS.has(key);\n}\n\n/**\n * Recursively checks if an object contains dangerous MongoDB operators.\n * \n * @param obj - The object to check\n * @param maxDepth - Maximum recursion depth (default: 10)\n * @returns True if dangerous operators found\n */\nexport function detectNoSqlInjection(obj: unknown, maxDepth = 10): boolean {\n  if (maxDepth <= 0) return false;\n  if (obj === null || typeof obj !== 'object') return false;\n  \n  if (Array.isArray(obj)) {\n    return obj.some(item => detectNoSqlInjection(item, maxDepth - 1));\n  }\n  \n  for (const key of Object.keys(obj as Record<string, unknown>)) {\n    if (isDangerousNoSqlKey(key)) {\n      return true;\n    }\n    \n    const value = (obj as Record<string, unknown>)[key];\n    if (typeof value === 'object' && value !== null) {\n      if (detectNoSqlInjection(value, maxDepth - 1)) {\n        return true;\n      }\n    }\n  }\n  \n  return false;\n}\n\n/**\n * Detects a MongoDB operator appearing in a STRING value.\n *\n * detectNoSqlInjection only inspects object keys. But operators also\n * arrive as strings: `?user[$ne]=1` reaches the handler as the literal\n * `$ne` before any object is built, and mongo-shell payloads like\n * `$where: '1==1'` are plain strings. This is the string-level check\n * used by block-mode scanThreats, matching Python's `_NOSQL_DETECT`.\n *\n * @param input - The string to check\n * @returns True if a NoSQL operator token is present\n *\n * @example\n * detectNoSqlString(\"$where: 'this.a==1'\") // true\n * detectNoSqlString(\"$invoice total\")      // false ($in not a token here)\n */\nexport function detectNoSqlString(input: string): boolean {\n  if (typeof input !== 'string') return false;\n  return NOSQL_STRING_PATTERN.test(input);\n}\n\n/**\n * Get list of all MongoDB operators considered dangerous.\n * Useful for documentation or custom validation.\n *\n * @returns Array of dangerous operator strings\n */\nexport function getDangerousOperators(): string[] {\n  return Array.from(NOSQL_DANGEROUS_KEYS);\n}\n","/**\n * @module @arcis/node/sanitizers/sanitize\n * Main sanitization functions that combine all sanitizers\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { INPUT, DANGEROUS_PROTO_KEYS, NOSQL_DANGEROUS_KEYS, AUTH_FIELDS } from '../core/constants';\nimport { InputTooLargeError, SecurityThreatError } from '../core/errors';\nimport type { SanitizeOptions } from '../core/types';\nimport { sanitizeXss, detectXss } from './xss';\nimport { sanitizeSql, detectSql } from './sql';\nimport { sanitizePath, detectPathTraversal } from './path';\nimport { sanitizeCommand, detectCommandInjection } from './command';\nimport { detectSsti } from './ssti';\nimport { detectXxe } from './xxe';\nimport { detectLdapInjection } from './ldap';\nimport { detectXpathInjection } from './xpath';\nimport { detectHeaderInjectionStrict } from './headers';\nimport { detectDeserialization } from './deserialization';\nimport { detectNoSqlString } from './nosql';\n\n/**\n * Sanitize a string value against multiple attack vectors.\n * \n * Order matters: We do XSS encoding LAST because:\n * 1. Other sanitizers need to see the original patterns (e.g., SQL keywords)\n * 2. HTML encoding is the final safe output transformation\n * 3. Encoded entities like &lt; shouldn't be treated as SQL/command threats\n * \n * @param value - The string to sanitize\n * @param options - Sanitization options\n * @returns The sanitized string\n * \n * @example\n * sanitizeString(\"<script>alert('xss')</script>\")\n * // Returns: \"&lt;script&gt;alert(&#x27;xss&#x27;)&lt;/script&gt;\"\n * \n * @example\n * sanitizeString(\"../../etc/passwd\")\n * // Returns: \"etc/passwd\"\n */\n/**\n * Decode URL + HTML entity layers until the string is stable.\n *\n * improvements.md §1.1.b — closes the encoding-stack bypass class.\n * A payload like `%2526%2523x3c%253bscript%2526%2523x3e%253b` is a\n * triple-encoded `<script>`: pass 1 URL-decodes to\n * `%26%23x3c%3bscript%26%23x3e%3b`, pass 2 URL-decodes to\n * `&#x3c;script&#x3e;`, pass 3 HTML-decodes to `<script>`. Without\n * this helper the literal ASCII `<script>` never appears in the\n * string, so the XSS regex never fires.\n *\n * Bounded at 4 passes to prevent pathological-input loops. Base64\n * decoding is intentionally NOT in the chain — false-positive rate\n * on arbitrary text would be high.\n */\nfunction multiDecode(value: string, maxPasses = 4): string {\n  for (let i = 0; i < maxPasses; i++) {\n    const prev = value;\n\n    // URL-decode. decodeURIComponent throws on malformed sequences\n    // (lone `%` with no hex pair); treat that as \"no further\n    // URL-decoding possible\" and continue with the current value.\n    try {\n      value = decodeURIComponent(value);\n    } catch {\n      // leave value as-is\n    }\n\n    // HTML entity decode. No built-in in Node, so inline the common\n    // entities here. Numeric (`&#NN;`, `&#xHH;`) covers the bulk of\n    // XSS-encoding tricks; the five named entities below cover the\n    // rest of the encoding-bypass test corpus.\n    value = htmlEntityDecode(value);\n\n    if (value === prev) break;\n  }\n  return value;\n}\n\n/** Decode HTML entities — numeric (decimal + hex) plus the five core\n * named entities that XSS payloads use. Keeps the dep-free zero-dep\n * footprint of `@arcis/node`. */\nfunction htmlEntityDecode(s: string): string {\n  // &#NN; decimal numeric\n  s = s.replace(/&#(\\d+);/g, (_m, n) => {\n    const code = parseInt(n, 10);\n    return Number.isFinite(code) && code >= 0 && code <= 0x10ffff\n      ? String.fromCodePoint(code)\n      : _m;\n  });\n  // &#xHH; or &#XHH; hex numeric\n  s = s.replace(/&#x([0-9a-fA-F]+);/g, (_m, h) => {\n    const code = parseInt(h, 16);\n    return Number.isFinite(code) && code >= 0 && code <= 0x10ffff\n      ? String.fromCodePoint(code)\n      : _m;\n  });\n  // The five named entities that matter for XSS detection.\n  const named: Record<string, string> = {\n    '&lt;': '<',\n    '&gt;': '>',\n    '&amp;': '&',\n    '&quot;': '\"',\n    '&apos;': \"'\",\n    '&nbsp;': ' ',\n  };\n  for (const [entity, ch] of Object.entries(named)) {\n    s = s.split(entity).join(ch);\n  }\n  return s;\n}\n\nexport function sanitizeString(value: string, options: SanitizeOptions = {}): string {\n  if (typeof value !== 'string') return value;\n\n  // Input size limit to prevent DoS\n  const maxSize = options.maxSize ?? INPUT.DEFAULT_MAX_SIZE;\n  if (value.length > maxSize) {\n    throw new InputTooLargeError(maxSize, value.length);\n  }\n\n  // Default mode is 'sanitize' (strip threats and return cleaned string).\n  // Pass mode: 'reject' to throw SecurityThreatError instead of stripping.\n  const reject = options.mode === 'reject';\n\n  // SECURITY: Normalize Unicode to NFKC BEFORE every detector runs.\n  // Fullwidth glyphs (`＜script＞`, `１+１＝２`) collapse to their ASCII\n  // equivalents, closing the entire fullwidth-bypass class for XSS,\n  // SQL, command-injection, and path-traversal in a single pass.\n  // improvements.md §1.1.a. Bypass example closed:\n  //   `＜script＞alert(1)＜/script＞`  →  `<script>alert(1)</script>`\n  let result = value.normalize('NFKC');\n\n  // SECURITY: Multi-pass URL + HTML decode (improvements.md §1.1.b).\n  // Closes the encoding-stack bypass class. After NFKC,\n  // `%2526%2523x3c%253bscript%2526%2523x3e%253b` (triple-encoded\n  // `<script>`) decodes all the way to `<script>` and hits the\n  // normal XSS strip below. Bounded at 4 passes.\n  result = multiDecode(result);\n\n  // 1. SQL injection\n  if (options.sql !== false) {\n    if (reject) {\n      if (detectSql(result)) {\n        throw new SecurityThreatError('sql_injection', 'SQL pattern detected in input');\n      }\n    } else {\n      result = sanitizeSql(result);\n    }\n  }\n\n  // 2. Path traversal prevention\n  if (options.path !== false) {\n    result = sanitizePath(result);\n  }\n\n  // 3. Command injection\n  if (options.command !== false) {\n    if (reject) {\n      if (detectCommandInjection(result)) {\n        throw new SecurityThreatError('command_injection', 'Shell metacharacter detected in input');\n      }\n    } else {\n      result = sanitizeCommand(result);\n    }\n  }\n\n  // 4. XSS stripping — always runs to remove dangerous patterns.\n  // HTML encoding is opt-in via options.htmlEncode (for SSR contexts only).\n  if (options.xss !== false) {\n    result = sanitizeXss(result, false, options.htmlEncode ?? false);\n  }\n\n  return result;\n}\n\n/**\n * Sanitize an object recursively, including nested objects and arrays.\n * Also removes prototype pollution and NoSQL injection keys.\n * \n * @param obj - The object to sanitize\n * @param options - Sanitization options\n * @returns The sanitized object\n */\nexport function sanitizeObject(obj: unknown, options: SanitizeOptions = {}): unknown {\n  if (obj === null || obj === undefined) return obj;\n  if (typeof obj === 'string') return sanitizeString(obj, options);\n  if (typeof obj !== 'object') return obj;\n  if (Array.isArray(obj)) return obj.map(item => sanitizeObject(item, options));\n\n  const result = sanitizeObjectDepth(obj as Record<string, unknown>, options, 0);\n  return options.freeze ? Object.freeze(result) : result;\n}\n\n/**\n * Internal recursive sanitization with depth tracking.\n */\nfunction sanitizeObjectDepth(\n  obj: Record<string, unknown>,\n  options: SanitizeOptions,\n  depth: number\n): Record<string, unknown> {\n  if (depth >= INPUT.MAX_RECURSION_DEPTH) return obj;\n\n  const result: Record<string, unknown> = {};\n\n  for (const key of Object.keys(obj)) {\n    // Prototype pollution protection - always block dangerous keys (case-insensitive)\n    if (options.proto !== false && DANGEROUS_PROTO_KEYS.has(key.toLowerCase())) {\n      continue;\n    }\n\n    // NoSQL injection - skip dangerous MongoDB operators in keys\n    if (options.nosql !== false && NOSQL_DANGEROUS_KEYS.has(key)) {\n      continue;\n    }\n\n    // Sanitize the key against all active threat vectors (not just XSS).\n    // Keys can carry injection payloads that bubble into query builders or ORMs.\n    const sanitizedKey = sanitizeString(key, options);\n\n    // Recursively sanitize value\n    const value = obj[key];\n    if (value === null || value === undefined) {\n      result[sanitizedKey] = value;\n    } else if (typeof value === 'string') {\n      result[sanitizedKey] = sanitizeString(value, options);\n    } else if (Array.isArray(value)) {\n      result[sanitizedKey] = value.map(item => sanitizeObject(item, options));\n    } else if (typeof value === 'object') {\n      result[sanitizedKey] = sanitizeObjectDepth(value as Record<string, unknown>, options, depth + 1);\n    } else {\n      result[sanitizedKey] = value;\n    }\n  }\n\n  return result;\n}\n\n/** Threat triple returned from scanThreats. */\nexport interface ThreatHit {\n  vector:\n    | 'xss'\n    | 'sql'\n    | 'nosql'\n    | 'path'\n    | 'command'\n    | 'prototype'\n    | 'ssti'\n    | 'xxe'\n    | 'ldap'\n    | 'xpath'\n    | 'header'\n    | 'deserialization';\n  rule: string;\n  matchedPattern: string;\n}\n\n/**\n * Walk a value (string, array, or object) and return the first threat hit\n * found. Used by block-mode middleware to attribute the deny decision.\n *\n * Vector ordering matches Python's scan_threats for cross-SDK parity.\n */\nexport function scanThreats(data: unknown, depth = 0): ThreatHit | null {\n  if (depth > INPUT.MAX_RECURSION_DEPTH) return null;\n\n  if (data && typeof data === 'object' && !Array.isArray(data)) {\n    for (const key of Object.keys(data as Record<string, unknown>)) {\n      const lower = key.toLowerCase();\n      if (DANGEROUS_PROTO_KEYS.has(lower)) {\n        return { vector: 'prototype', rule: 'prototype/match', matchedPattern: key };\n      }\n      if (NOSQL_DANGEROUS_KEYS.has(key)) {\n        return { vector: 'nosql', rule: 'nosql/match', matchedPattern: key };\n      }\n      const value = (data as Record<string, unknown>)[key];\n      // NoSQL type-juggling: an auth/identity field whose value is an\n      // ARRAY instead of a scalar (e.g. {\"username\":[\"admin\"]}). MongoDB\n      // turns the array into an $in-style operator, bypassing string\n      // equality. Only arrays are flagged: operator-objects ({\"$ne\":...})\n      // are caught by NOSQL_DANGEROUS_KEYS, and a plain nested object under\n      // an auth field is legitimate. Benchmark nosql-mongo-type-juggle.\n      if (AUTH_FIELDS.has(lower) && Array.isArray(value)) {\n        return { vector: 'nosql', rule: 'nosql/type-juggle', matchedPattern: key };\n      }\n      const inner = scanThreats(value, depth + 1);\n      if (inner) return inner;\n    }\n    return null;\n  }\n\n  if (Array.isArray(data)) {\n    for (const item of data) {\n      const inner = scanThreats(item, depth + 1);\n      if (inner) return inner;\n    }\n    return null;\n  }\n\n  if (typeof data !== 'string') return null;\n\n  // SECURITY: normalize the SAME way sanitizeString does before any\n  // detector runs, so block-mode detection honors the NFKC + multi-decode\n  // bypass protection. Without this, block mode missed fullwidth\n  // `<script>` (U+FF1C), `%3Cscript%3E`, and HTML-entity-encoded payloads\n  // that sanitize-mode already caught. (v1.7 parity fix 2026-06-08.)\n  const norm = multiDecode(data.normalize('NFKC'));\n\n  const sample = norm.slice(0, 80);\n  // __proto__ as a STRING VALUE (e.g. [\"__proto__\",\"isAdmin\"] gadget-chain\n  // path array). The key-based check above only sees object keys; a dunder\n  // proto token as a value is the array-form signal. Only the dunder forms\n  // (never legit prose) are flagged, so the words \"constructor\"/\"prototype\"\n  // in normal text don't trip it. Benchmark proto-pollution-array-index.\n  if (norm.includes('__proto__')) {\n    return { vector: 'prototype', rule: 'prototype/match', matchedPattern: sample };\n  }\n  if (detectXss(norm)) {\n    return { vector: 'xss', rule: 'xss/match', matchedPattern: sample };\n  }\n  if (detectSsti(norm)) {\n    return { vector: 'ssti', rule: 'ssti/match', matchedPattern: sample };\n  }\n  if (detectXxe(norm)) {\n    return { vector: 'xxe', rule: 'xxe/match', matchedPattern: sample };\n  }\n  // Deserialization markers (pickle incl. base64, Ruby Marshal, .NET,\n  // FastJSON, PHP). Wired into block mode in v1.7 (was detection-only).\n  const deser = detectDeserialization(norm);\n  if (deser) {\n    return { vector: 'deserialization', rule: `deserialization/${deser}`, matchedPattern: sample };\n  }\n  if (detectSql(norm)) {\n    return { vector: 'sql', rule: 'sql/match', matchedPattern: sample };\n  }\n  // Path detection runs on the RAW string so the encoded-form patterns\n  // (%C0%AE overlong UTF-8, %2e%2e, %252f) still fire; multiDecode would\n  // otherwise strip them. The decoded `../` form survives in raw too.\n  if (detectPathTraversal(data) || detectPathTraversal(norm)) {\n    return { vector: 'path', rule: 'path/match', matchedPattern: sample };\n  }\n  if (detectCommandInjection(norm)) {\n    return { vector: 'command', rule: 'command/match', matchedPattern: sample };\n  }\n  // LDAP + XPath checks come AFTER command/path so a string that's\n  // primarily a path-traversal payload (`../`) gets attributed to\n  // path, not LDAP (the `\\` in `..\\..\\` would otherwise hit the LDAP\n  // backslash filter).\n  if (detectLdapInjection(norm)) {\n    return { vector: 'ldap', rule: 'ldap/match', matchedPattern: sample };\n  }\n  if (detectXpathInjection(norm)) {\n    return { vector: 'xpath', rule: 'xpath/match', matchedPattern: sample };\n  }\n  // Header injection (HTTP response splitting + email-header injection\n  // share the same byte-level threat: CRLF in a value that gets\n  // concatenated into a header). Last in the chain so the more-specific\n  // detectors (xss / sql / etc.) win on input that's both — e.g. an XSS\n  // payload with a stray newline still attributes to xss.\n  if (detectHeaderInjectionStrict(norm)) {\n    return { vector: 'header', rule: 'header/match', matchedPattern: sample };\n  }\n  // String-form NoSQL operator (`$where`, `$ne`, `[$gt]`) carried in a\n  // string value rather than an object key. Last in the chain so the\n  // more-specific detectors above win; this only catches operator tokens\n  // that would otherwise pass through. Closes the Node-vs-Python NoSQL\n  // string parity gap (GoTestWAF NoSQL was 0% on Node).\n  if (detectNoSqlString(norm)) {\n    return { vector: 'nosql', rule: 'nosql/string', matchedPattern: sample };\n  }\n  return null;\n}\n\n/**\n * Create Express middleware for request sanitization.\n * Sanitizes req.body, req.query, and req.params.\n * \n * @param options - Sanitization options\n * @returns Express middleware\n * \n * @example\n * app.use(createSanitizer());\n * \n * @example\n * app.use(createSanitizer({ xss: true, sql: true, nosql: true }));\n */\nexport function createSanitizer(options: SanitizeOptions = {}): RequestHandler {\n  return (req: Request, res: Response, next: NextFunction) => {\n    try {\n      // Block mode: scan first, return 403 on threat. The telemetry emitter\n      // reads the marker on res.finish to attribute the deny decision.\n      if (options.block) {\n        const hit =\n          scanThreats(req.body) ||\n          scanThreats(req.query) ||\n          scanThreats(req.params) ||\n          scanThreats(req.path);\n        if (hit) {\n          req.__arcis = {\n            vector: hit.vector,\n            rule: hit.rule,\n            severity: 'high',\n            matchedPattern: hit.matchedPattern,\n            reason: `${hit.vector} pattern detected in request`,\n            decision: 'deny',\n          };\n          res.status(403).json({\n            error: 'Request blocked for security reasons',\n            code: 'SECURITY_THREAT',\n            vector: hit.vector,\n          });\n          return;\n        }\n      }\n\n      if (req.body && typeof req.body === 'object') {\n        req.body = sanitizeObject(req.body, options);\n      }\n      if (req.query && typeof req.query === 'object') {\n        const sanitizedQuery = sanitizeObject(req.query, options);\n        // Express 5: req.query is a getter with no setter — override on instance\n        Object.defineProperty(req, 'query', { value: sanitizedQuery, writable: true, configurable: true });\n      }\n      if (req.params && typeof req.params === 'object') {\n        const sanitizedParams = sanitizeObject(req.params, options);\n        Object.defineProperty(req, 'params', { value: sanitizedParams, writable: true, configurable: true });\n      }\n      next();\n    } catch (err) {\n      next(err);\n    }\n  };\n}\n","/**\n * @module @arcis/node/validation/schema\n * Request validation middleware\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { VALIDATION, ERRORS } from '../core/constants';\nimport type { ValidationSchema, FieldValidator } from '../core/types';\nimport { sanitizeString } from '../sanitizers';\n\n/**\n * Create Express middleware for request validation.\n * Prevents mass assignment by only allowing fields defined in the schema.\n * \n * @param schema - Validation schema defining expected fields\n * @param source - Request property to validate ('body', 'query', or 'params')\n * @returns Express middleware\n * \n * @example\n * app.post('/users', validate({\n *   email: { type: 'email', required: true },\n *   name: { type: 'string', min: 2, max: 50 },\n *   age: { type: 'number', min: 0, max: 150 },\n *   role: { type: 'string', enum: ['user', 'admin'] }\n * }), handler);\n * \n * @example\n * // Validate query params\n * app.get('/search', validate({\n *   q: { type: 'string', required: true, min: 1 },\n *   page: { type: 'number', min: 1 }\n * }, 'query'), handler);\n */\nexport function validate(\n  schema: ValidationSchema,\n  source: 'body' | 'query' | 'params' = 'body'\n): RequestHandler {\n  return (req: Request, res: Response, next: NextFunction) => {\n    const data = req[source] || {};\n    const errors: string[] = [];\n    const validated: Record<string, unknown> = {};\n\n    for (const [field, rules] of Object.entries(schema)) {\n      const value = data[field];\n      const result = validateField(field, value, rules);\n      \n      if (result.errors.length > 0) {\n        errors.push(...result.errors);\n      } else if (result.value !== undefined) {\n        validated[field] = result.value;\n      }\n    }\n\n    if (errors.length > 0) {\n      res.status(400).json({ errors });\n      return;\n    }\n\n    // Replace with validated data (prevents mass assignment).\n    // SECURITY: Express 5 makes req.body/query/params read-only. Use\n    // defineProperty so this works on both Express 4 and 5; direct\n    // assignment crashes Express 5 with TypeError.\n    Object.defineProperty(req, source, {\n      value: validated,\n      writable: true,\n      configurable: true,\n      enumerable: true,\n    });\n    next();\n  };\n}\n\n/**\n * Validate a single field against its rules.\n */\nfunction validateField(\n  field: string,\n  value: unknown,\n  rules: FieldValidator\n): { value?: unknown; errors: string[] } {\n  const errors: string[] = [];\n\n  // Required check\n  if (rules.required && (value === undefined || value === null || value === '')) {\n    errors.push(ERRORS.VALIDATION.REQUIRED(field));\n    return { errors };\n  }\n\n  // Skip optional empty fields\n  if (value === undefined || value === null) {\n    return { errors: [] };\n  }\n\n  let typedValue: unknown = value;\n  let isValid = true;\n\n  // Type validation and coercion\n  switch (rules.type) {\n    case 'string':\n      if (typeof value !== 'string') {\n        errors.push(ERRORS.VALIDATION.INVALID_TYPE(field, 'string'));\n        isValid = false;\n        break;\n      }\n      if (rules.min !== undefined && value.length < rules.min) {\n        errors.push(ERRORS.VALIDATION.MIN_LENGTH(field, rules.min));\n        isValid = false;\n      }\n      if (rules.max !== undefined && value.length > rules.max) {\n        errors.push(ERRORS.VALIDATION.MAX_LENGTH(field, rules.max));\n        isValid = false;\n      }\n      if (rules.pattern && !rules.pattern.test(value)) {\n        errors.push(ERRORS.VALIDATION.INVALID_FORMAT(field));\n        isValid = false;\n      }\n      // Enum check runs before sanitization so the raw value is compared.\n      // Sanitizing first could silently modify the value and cause a mismatch\n      // with enum entries that contain characters the sanitizer would strip.\n      if (isValid && rules.enum && !rules.enum.includes(value)) {\n        errors.push(ERRORS.VALIDATION.INVALID_ENUM(field, rules.enum));\n        isValid = false;\n      }\n      if (isValid && rules.sanitize !== false) {\n        typedValue = sanitizeString(value);\n      }\n      break;\n\n    case 'number':\n      typedValue = Number(value);\n      if (isNaN(typedValue as number)) {\n        errors.push(ERRORS.VALIDATION.INVALID_TYPE(field, 'number'));\n        isValid = false;\n        break;\n      }\n      if (rules.min !== undefined && (typedValue as number) < rules.min) {\n        errors.push(ERRORS.VALIDATION.MIN_VALUE(field, rules.min));\n        isValid = false;\n      }\n      if (rules.max !== undefined && (typedValue as number) > rules.max) {\n        errors.push(ERRORS.VALIDATION.MAX_VALUE(field, rules.max));\n        isValid = false;\n      }\n      break;\n\n    case 'boolean':\n      if (value === 'true' || value === true || value === 1 || value === '1') {\n        typedValue = true;\n      } else if (value === 'false' || value === false || value === 0 || value === '0') {\n        typedValue = false;\n      } else {\n        errors.push(ERRORS.VALIDATION.INVALID_TYPE(field, 'boolean'));\n        isValid = false;\n      }\n      break;\n\n    case 'email':\n      if (!VALIDATION.EMAIL.test(String(value))) {\n        errors.push(ERRORS.VALIDATION.INVALID_EMAIL(field));\n        isValid = false;\n      }\n      if (isValid) {\n        typedValue = sanitizeString(String(value).toLowerCase().trim());\n      }\n      break;\n\n    case 'url':\n      if (!VALIDATION.URL.test(String(value))) {\n        errors.push(ERRORS.VALIDATION.INVALID_URL(field));\n        isValid = false;\n      }\n      if (isValid) {\n        typedValue = sanitizeString(String(value));\n      }\n      break;\n\n    case 'uuid':\n      if (!VALIDATION.UUID.test(String(value))) {\n        errors.push(ERRORS.VALIDATION.INVALID_UUID(field));\n        isValid = false;\n      }\n      break;\n\n    case 'array':\n      if (!Array.isArray(value)) {\n        errors.push(ERRORS.VALIDATION.INVALID_TYPE(field, 'array'));\n        isValid = false;\n        break;\n      }\n      if (rules.min !== undefined && value.length < rules.min) {\n        errors.push(ERRORS.VALIDATION.MIN_ITEMS(field, rules.min));\n        isValid = false;\n      }\n      if (rules.max !== undefined && value.length > rules.max) {\n        errors.push(ERRORS.VALIDATION.MAX_ITEMS(field, rules.max));\n        isValid = false;\n      }\n      break;\n\n    case 'object':\n      if (typeof value !== 'object' || Array.isArray(value) || value === null) {\n        errors.push(ERRORS.VALIDATION.INVALID_TYPE(field, 'object'));\n        isValid = false;\n      }\n      break;\n  }\n\n  // Enum validation for non-string types (strings check enum before sanitizing above).\n  if (isValid && rules.enum && rules.type !== 'string' && !rules.enum.includes(typedValue)) {\n    errors.push(ERRORS.VALIDATION.INVALID_ENUM(field, rules.enum));\n    isValid = false;\n  }\n\n  // Custom validation\n  if (isValid && rules.custom) {\n    const customResult = rules.custom(typedValue);\n    if (customResult === undefined) {\n      throw new TypeError(\n        `Custom validator for field \"${field}\" returned undefined. ` +\n        'Return true to pass, false to fail, or a string error message.'\n      );\n    }\n    if (customResult !== true) {\n      errors.push(typeof customResult === 'string' && customResult.length > 0 ? customResult : `${field} is invalid`);\n      isValid = false;\n    }\n  }\n\n  return {\n    value: isValid ? typedValue : undefined,\n    errors,\n  };\n}\n\n/**\n * Alias for validate\n * @see validate\n */\nexport const createValidator = validate;\n","/**\n * @module @arcis/node/validation/file\n * File upload validation and filename sanitization\n */\n\n// =============================================================================\n// MAGIC BYTES — first bytes of common file types\n// =============================================================================\n\nconst MAGIC_BYTES: Record<string, Buffer[]> = {\n  // Images\n  'image/jpeg': [Buffer.from([0xFF, 0xD8, 0xFF])],\n  'image/png': [Buffer.from([0x89, 0x50, 0x4E, 0x47])],\n  'image/gif': [Buffer.from('GIF87a'), Buffer.from('GIF89a')],\n  'image/webp': [Buffer.from('RIFF')], // RIFF....WEBP\n  'image/bmp': [Buffer.from([0x42, 0x4D])],\n  'image/svg+xml': [], // text-based, check separately\n\n  // Documents\n  'application/pdf': [Buffer.from('%PDF')],\n  'application/zip': [Buffer.from([0x50, 0x4B, 0x03, 0x04])],\n\n  // Audio/Video\n  'audio/mpeg': [Buffer.from([0xFF, 0xFB]), Buffer.from([0xFF, 0xF3]), Buffer.from([0x49, 0x44, 0x33])],\n  'video/mp4': [], // ftyp at offset 4\n};\n\n// =============================================================================\n// DANGEROUS EXTENSIONS — files that can execute code\n// =============================================================================\n\nconst DANGEROUS_EXTENSIONS = new Set([\n  // Scripts\n  '.exe', '.bat', '.cmd', '.com', '.msi', '.scr', '.pif',\n  '.vbs', '.vbe', '.js', '.jse', '.ws', '.wsf', '.wsc', '.wsh',\n  '.ps1', '.ps1xml', '.ps2', '.ps2xml', '.psc1', '.psc2',\n  '.sh', '.bash', '.csh', '.ksh',\n  // Server-side\n  '.php', '.php3', '.php4', '.php5', '.phtml', '.pht',\n  '.asp', '.aspx', '.ashx', '.asmx', '.cer',\n  '.jsp', '.jspx', '.jsw', '.jsv',\n  '.cgi', '.pl', '.py', '.rb',\n  // Java\n  '.jar', '.war', '.ear', '.class',\n  // Config that can execute\n  '.htaccess', '.htpasswd',\n  // Template engines\n  '.ejs', '.pug', '.hbs', '.handlebars', '.njk', '.twig',\n  // Shortcuts/links\n  '.lnk', '.inf', '.reg', '.url',\n  // Office macros\n  '.docm', '.xlsm', '.pptm', '.dotm',\n]);\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/** File upload validation options */\nexport interface ValidateFileOptions {\n  /** Maximum file size in bytes. Default: 5MB */\n  maxSize?: number;\n  /** Allowed MIME types (e.g., ['image/jpeg', 'image/png']) */\n  allowedTypes?: string[];\n  /** Allowed file extensions (e.g., ['.jpg', '.png']). Includes dot. */\n  allowedExtensions?: string[];\n  /** Block dangerous/executable extensions. Default: true */\n  blockExecutables?: boolean;\n  /** Validate magic bytes match the claimed MIME type. Default: true */\n  validateMagicBytes?: boolean;\n  /** Block files with no extension. Default: true */\n  blockNoExtension?: boolean;\n  /** Block double extensions (e.g., file.php.jpg). Default: true */\n  blockDoubleExtensions?: boolean;\n}\n\n/** File metadata for validation */\nexport interface FileInput {\n  /** Original filename */\n  filename: string;\n  /** MIME type (as claimed by client) */\n  mimetype: string;\n  /** File size in bytes */\n  size: number;\n  /** File content buffer (for magic byte validation) */\n  buffer?: Buffer;\n}\n\n/** File validation result */\nexport interface ValidateFileResult {\n  /** Whether the file passed validation */\n  valid: boolean;\n  /** Validation errors (empty if valid) */\n  errors: string[];\n  /** Sanitized filename (safe for storage) */\n  sanitizedFilename: string;\n}\n\n// =============================================================================\n// DEFAULTS\n// =============================================================================\n\nconst DEFAULT_MAX_SIZE = 5 * 1024 * 1024; // 5MB\n\n// =============================================================================\n// FILENAME SANITIZATION\n// =============================================================================\n\n/**\n * Sanitize a filename for safe storage.\n *\n * Strips path traversal, null bytes, control characters, and special characters.\n * Preserves the extension and converts to a filesystem-safe name.\n *\n * @param filename - The original filename\n * @returns A sanitized filename safe for storage\n *\n * @example\n * sanitizeFilename('../../etc/passwd')          // 'etc_passwd'\n * sanitizeFilename('file<name>.jpg')            // 'filename.jpg'\n * sanitizeFilename('photo (1).jpg')             // 'photo_1.jpg'\n * sanitizeFilename('.htaccess')                 // 'htaccess'\n */\nexport function sanitizeFilename(filename: string): string {\n  let name = filename;\n\n  // Strip null bytes\n  name = name.replace(/\\0/g, '');\n\n  // Strip path components (both Unix and Windows)\n  name = name.replace(/^.*[/\\\\]/, '');\n\n  // Strip control characters\n  name = name.replace(/[\\x00-\\x1F\\x7F]/g, '');\n\n  // Strip characters unsafe for filesystems\n  name = name.replace(/[<>:\"/\\\\|?*]/g, '');\n\n  // Replace spaces and parens with underscores\n  name = name.replace(/[\\s()]+/g, '_');\n\n  // Strip leading dots (hidden files / .htaccess)\n  name = name.replace(/^\\.+/, '');\n\n  // Collapse multiple underscores/dots\n  name = name.replace(/_{2,}/g, '_');\n  name = name.replace(/\\.{2,}/g, '.');\n\n  // Trim underscores before dots (e.g., \"photo_1_.jpg\" → \"photo_1.jpg\")\n  name = name.replace(/_+\\./g, '.');\n\n  // Trim underscores from edges\n  name = name.replace(/^_+|_+$/g, '');\n\n  // Fallback for empty name\n  if (!name || name === '.') {\n    name = 'unnamed';\n  }\n\n  return name;\n}\n\n// =============================================================================\n// MAGIC BYTE VALIDATION\n// =============================================================================\n\n/**\n * Check if file content matches the claimed MIME type via magic bytes.\n */\nfunction matchesMagicBytes(buffer: Buffer, mimetype: string): boolean {\n  const signatures = MAGIC_BYTES[mimetype];\n  if (!signatures || signatures.length === 0) return true; // no signature to check\n\n  return signatures.some(sig => {\n    if (buffer.length < sig.length) return false;\n    return buffer.subarray(0, sig.length).equals(sig);\n  });\n}\n\n// =============================================================================\n// EXTENSION HELPERS\n// =============================================================================\n\n/**\n * Get the extension from a filename (lowercase, with dot).\n */\nfunction getExtension(filename: string): string {\n  const lastDot = filename.lastIndexOf('.');\n  if (lastDot < 1) return '';\n  return filename.slice(lastDot).toLowerCase();\n}\n\n/**\n * Check if a filename has double extensions (e.g., file.php.jpg).\n */\nfunction hasDoubleExtension(filename: string): boolean {\n  const parts = filename.split('.');\n  if (parts.length < 3) return false;\n\n  // Check if any non-final extension is dangerous\n  for (let i = 1; i < parts.length - 1; i++) {\n    const ext = '.' + parts[i].toLowerCase();\n    if (DANGEROUS_EXTENSIONS.has(ext)) return true;\n  }\n  return false;\n}\n\n// =============================================================================\n// FILE VALIDATION\n// =============================================================================\n\n/**\n * Validate a file upload for security.\n *\n * Checks file size, MIME type, extension, magic bytes, and dangerous patterns.\n * Returns a result with validation errors and a sanitized filename.\n *\n * @param file - File metadata and optional content\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * const result = validateFile(\n *   { filename: 'photo.jpg', mimetype: 'image/jpeg', size: 1024, buffer },\n *   { allowedTypes: ['image/jpeg', 'image/png'], maxSize: 2 * 1024 * 1024 }\n * );\n * if (!result.valid) {\n *   return res.status(400).json({ errors: result.errors });\n * }\n * // Use result.sanitizedFilename for storage\n *\n * @example\n * // Block executables only (no whitelist)\n * const result = validateFile(file, { blockExecutables: true });\n */\nexport function validateFile(\n  file: FileInput,\n  options: ValidateFileOptions = {}\n): ValidateFileResult {\n  const {\n    maxSize = DEFAULT_MAX_SIZE,\n    allowedTypes,\n    allowedExtensions,\n    blockExecutables = true,\n    validateMagicBytes = true,\n    blockNoExtension = true,\n    blockDoubleExtensions = true,\n  } = options;\n\n  const errors: string[] = [];\n  const sanitizedFilename = sanitizeFilename(file.filename);\n  const extension = getExtension(sanitizedFilename);\n\n  // Size check\n  if (file.size > maxSize) {\n    errors.push(`File size ${file.size} exceeds maximum ${maxSize} bytes`);\n  }\n\n  if (file.size === 0) {\n    errors.push('File is empty');\n  }\n\n  // Extension checks\n  if (blockNoExtension && !extension) {\n    errors.push('File has no extension');\n  }\n\n  if (blockExecutables && extension && DANGEROUS_EXTENSIONS.has(extension)) {\n    errors.push(`Executable extension \"${extension}\" is not allowed`);\n  }\n\n  if (blockDoubleExtensions && hasDoubleExtension(sanitizedFilename)) {\n    errors.push('Double extensions with executable types are not allowed');\n  }\n\n  if (allowedExtensions && extension) {\n    const normalizedAllowed = allowedExtensions.map(e => e.toLowerCase());\n    if (!normalizedAllowed.includes(extension)) {\n      errors.push(`Extension \"${extension}\" is not allowed. Allowed: ${normalizedAllowed.join(', ')}`);\n    }\n  }\n\n  // MIME type check\n  if (allowedTypes && !allowedTypes.includes(file.mimetype)) {\n    errors.push(`MIME type \"${file.mimetype}\" is not allowed. Allowed: ${allowedTypes.join(', ')}`);\n  }\n\n  // Magic bytes validation\n  if (validateMagicBytes && file.buffer && file.buffer.length > 0) {\n    if (!matchesMagicBytes(file.buffer, file.mimetype)) {\n      errors.push(`File content does not match claimed MIME type \"${file.mimetype}\"`);\n    }\n  }\n\n  return {\n    valid: errors.length === 0,\n    errors,\n    sanitizedFilename,\n  };\n}\n\n/**\n * Check if a file extension is considered dangerous/executable.\n *\n * @param filename - Filename or extension to check\n * @returns true if the extension is dangerous\n */\nexport function isDangerousExtension(filename: string): boolean {\n  const ext = getExtension(filename);\n  return ext !== '' && DANGEROUS_EXTENSIONS.has(ext);\n}\n","/**\n * @module @arcis/node/logging/redactor\n * Safe logging with PII/secret redaction\n */\n\nimport { REDACTION, INPUT } from '../core/constants';\nimport type { LogOptions, SafeLogger } from '../core/types';\n\nconst LOG_LEVELS: Record<string, number> = {\n  debug: 0,\n  info: 1,\n  warn: 2,\n  error: 3,\n  silent: 4,\n};\n\n/**\n * Create a safe logger that redacts sensitive data and prevents log injection.\n * \n * @param options - Logger configuration\n * @returns SafeLogger instance\n * \n * @example\n * const logger = createSafeLogger();\n * logger.info('User login', { email: 'user@test.com', password: 'secret' });\n * // Logs: { \"email\": \"user@test.com\", \"password\": \"[REDACTED]\" }\n * \n * @example\n * // With custom redact keys\n * const logger = createSafeLogger({ redactKeys: ['customToken', 'internalId'] });\n */\nexport function createSafeLogger(options: LogOptions = {}): SafeLogger {\n  const {\n    redactKeys = [],\n    maxLength = REDACTION.DEFAULT_MAX_LENGTH,\n    redactPatterns = [],\n    level: minLevel = 'debug',\n  } = options;\n\n  const minLevelNum = LOG_LEVELS[minLevel] ?? 0;\n\n  // Combine default and custom keys (lowercase for case-insensitive matching)\n  const allRedactKeys = new Set([\n    ...Array.from(REDACTION.SENSITIVE_KEYS),\n    ...redactKeys.map(k => k.toLowerCase()),\n  ]);\n\n  /**\n   * Redact sensitive data from an object recursively.\n   */\n  function redact(obj: unknown, depth = 0): unknown {\n    if (depth > INPUT.MAX_RECURSION_DEPTH) return REDACTION.MAX_DEPTH;\n    if (obj === null || obj === undefined) return obj;\n\n    if (typeof obj === 'string') {\n      return redactString(obj, maxLength, redactPatterns);\n    }\n\n    if (typeof obj !== 'object') return obj;\n\n    if (Array.isArray(obj)) {\n      return obj.map(item => redact(item, depth + 1));\n    }\n\n    const result: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n      if (allRedactKeys.has(key.toLowerCase())) {\n        result[key] = REDACTION.REPLACEMENT;\n      } else {\n        result[key] = redact(value, depth + 1);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Log a message at the specified level.\n   */\n  function log(level: string, message: string, data?: unknown): void {\n    // Early exit: skip all work if message level is below minimum\n    const levelNum = LOG_LEVELS[level] ?? 0;\n    if (levelNum < minLevelNum) return;\n\n    const entry: Record<string, unknown> = {\n      timestamp: new Date().toISOString(),\n      level,\n      message: redactString(message, maxLength, redactPatterns),\n    };\n\n    if (data !== undefined) {\n      entry.data = redact(data);\n    }\n\n    // eslint-disable-next-line no-console\n    console.log(JSON.stringify(entry));\n  }\n\n  return {\n    log,\n    info: (msg: string, data?: unknown) => log('info', msg, data),\n    warn: (msg: string, data?: unknown) => log('warn', msg, data),\n    error: (msg: string, data?: unknown) => log('error', msg, data),\n    debug: (msg: string, data?: unknown) => log('debug', msg, data),\n  };\n}\n\n/**\n * Redact a string value.\n * Removes newlines (log injection prevention), applies patterns, and truncates.\n */\nfunction redactString(str: string, maxLength: number, patterns: RegExp[]): string {\n  // Remove newlines/tabs (log injection prevention) and genuine control characters.\n  // Only strip C0/C1 control chars and null bytes — preserve all printable Unicode\n  // (CJK, Cyrillic, Arabic, etc.) so multilingual content isn't silently lost.\n  let safe = str\n    .replace(/[\\r\\n\\t]/g, ' ')\n    .replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F\\x80-\\x9F]/g, '');\n\n  // Apply custom redaction patterns\n  for (const pattern of patterns) {\n    safe = safe.replace(pattern, REDACTION.REPLACEMENT);\n  }\n\n  // Truncate if too long\n  if (safe.length > maxLength) {\n    safe = safe.substring(0, maxLength) + `...${REDACTION.TRUNCATED}`;\n  }\n\n  return safe;\n}\n\n/**\n * Create a redactor function for custom use.\n * \n * @param sensitiveKeys - Keys to redact\n * @returns Redactor function\n */\nexport function createRedactor(sensitiveKeys: string[] = []): (obj: unknown) => unknown {\n  const allKeys = new Set([\n    ...Array.from(REDACTION.SENSITIVE_KEYS),\n    ...sensitiveKeys.map(k => k.toLowerCase()),\n  ]);\n\n  function redact(obj: unknown, depth = 0): unknown {\n    if (depth > INPUT.MAX_RECURSION_DEPTH) return REDACTION.MAX_DEPTH;\n    if (obj === null || obj === undefined) return obj;\n    if (typeof obj !== 'object') return obj;\n\n    if (Array.isArray(obj)) {\n      return obj.map(item => redact(item, depth + 1));\n    }\n\n    const result: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n      if (allKeys.has(key.toLowerCase())) {\n        result[key] = REDACTION.REPLACEMENT;\n      } else {\n        result[key] = redact(value, depth + 1);\n      }\n    }\n    return result;\n  }\n\n  return redact;\n}\n\n/**\n * Alias for createSafeLogger\n * @see createSafeLogger\n */\nexport const safeLog = createSafeLogger;\n","import type { TelemetryEvent, TelemetryOptions } from './types';\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst MAX_BATCH_SIZE = 500; // matches server Zod schema upper bound\nconst DEFAULT_FLUSH_INTERVAL_MS = 5000;\nconst MIN_FLUSH_INTERVAL_MS = 500;\nconst FLUSH_TIMEOUT_MS = 10_000;\nconst DEFAULT_MAX_QUEUE_SIZE = 10_000;\n\ntype Listener = (err: Error) => void;\ntype OverflowListener = (droppedCount: number) => void;\n\n/**\n * In-memory batching client that ships `TelemetryEvent` objects to an\n * Arcis dashboard server.\n *\n * Design rules (spec/API_SPEC.md §9):\n *   1. `record()` is synchronous and never throws — safe to call from hot paths.\n *   2. Flushes trigger on batchSize OR flushIntervalMs, whichever comes first.\n *   3. Network errors are fail-open: they call `onError` (if provided) and\n *      drop the batch. No retry, no disk persistence, no backpressure.\n *   4. `close()` attempts one final flush; safe to call multiple times.\n *   5. Interval timer uses `unref()` so it never holds the process open.\n */\nexport class TelemetryClient {\n  private queue: TelemetryEvent[] = [];\n  private readonly endpoint: string;\n  private readonly apiKey: string | undefined;\n  private readonly workspaceId: string | undefined;\n  private readonly batchSize: number;\n  private readonly flushIntervalMs: number;\n  private readonly maxQueueSize: number;\n  private readonly onError: Listener;\n  private readonly onQueueOverflow: OverflowListener;\n  private timer: ReturnType<typeof setInterval> | undefined;\n  private flushing = false;\n  private closed = false;\n  private signalHandler: (() => void) | undefined;\n  // Counts events dropped since the last successful flush. Resets to 0\n  // each flush so onQueueOverflow callbacks see \"drops in this window\"\n  // rather than a monotonic lifetime counter.\n  private droppedSinceLastFlush = 0;\n\n  constructor(options: TelemetryOptions) {\n    if (!options.endpoint || typeof options.endpoint !== 'string') {\n      throw new TypeError('TelemetryClient: `endpoint` is required');\n    }\n\n    this.endpoint = options.endpoint;\n    this.apiKey = options.apiKey;\n    this.workspaceId = options.workspaceId;\n    this.batchSize = clamp(\n      options.batchSize ?? DEFAULT_BATCH_SIZE,\n      1,\n      MAX_BATCH_SIZE,\n    );\n    this.flushIntervalMs = Math.max(\n      options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,\n      MIN_FLUSH_INTERVAL_MS,\n    );\n    // Cap the in-memory queue to bound memory under sustained dashboard\n    // outage. Drop-oldest semantics preserve the most recent events,\n    // which are usually the most relevant for incident triage.\n    this.maxQueueSize = Math.max(\n      options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE,\n      this.batchSize,\n    );\n    this.onError = options.onError ?? (() => {\n      // default: swallow silently (fail-open)\n    });\n    this.onQueueOverflow = options.onQueueOverflow ?? (() => {\n      // default: silent — operators can opt in to logging\n    });\n\n    this.startTimer();\n  }\n\n  /**\n   * Enqueue an event. Fast, synchronous, cannot throw.\n   * Triggers a flush if the queue has reached `batchSize`.\n   */\n  record(event: TelemetryEvent): void {\n    if (this.closed) return;\n    this.queue.push(event);\n\n    // Cap the queue at maxQueueSize. Drop oldest events (FIFO) so we keep\n    // the freshest signal during a sustained outage. Without this cap, a\n    // 24h dashboard outage at moderate traffic OOMs the worker.\n    if (this.queue.length > this.maxQueueSize) {\n      const drop = this.queue.length - this.maxQueueSize;\n      this.queue.splice(0, drop);\n      this.droppedSinceLastFlush += drop;\n      try {\n        this.onQueueOverflow(this.droppedSinceLastFlush);\n      } catch {\n        // overflow callback errors must not break record()\n      }\n    }\n\n    if (this.queue.length >= this.batchSize) {\n      // fire and forget\n      void this.flush();\n    }\n  }\n\n  /**\n   * Manually flush the queue. Pulls up to `batchSize` events into a batch and\n   * POSTs them. Returns a resolved promise on success OR on handled failure.\n   * Never throws.\n   */\n  async flush(): Promise<void> {\n    if (this.flushing) return;\n    if (this.queue.length === 0) return;\n\n    this.flushing = true;\n    try {\n      const batch = this.queue.splice(0, this.batchSize);\n      await this.send(batch);\n      // Successful flush — reset overflow counter so subsequent drops\n      // start a fresh window. A connected dashboard \"clears\" the alert.\n      this.droppedSinceLastFlush = 0;\n    } catch (err) {\n      this.safeNotify(err);\n    } finally {\n      this.flushing = false;\n    }\n\n    // Drain anything that arrived while we were flushing.\n    if (!this.closed && this.queue.length > 0) {\n      void this.flush();\n    }\n  }\n\n  /**\n   * Shut down: stop the interval timer and attempt one final flush.\n   * Safe to call multiple times.\n   */\n  async close(): Promise<void> {\n    if (this.closed) return;\n    this.closed = true;\n\n    if (this.timer !== undefined) {\n      clearInterval(this.timer);\n      this.timer = undefined;\n    }\n\n    if (this.signalHandler !== undefined) {\n      process.off('SIGTERM', this.signalHandler);\n      process.off('SIGINT', this.signalHandler);\n      this.signalHandler = undefined;\n    }\n\n    // final best-effort flush\n    try {\n      await this.flush();\n    } catch {\n      // fail-open on shutdown\n    }\n  }\n\n  /**\n   * Register `SIGTERM` / `SIGINT` handlers that call `close()` to drain\n   * the queue on graceful shutdown. Opt-in — libraries should not silently\n   * attach global signal handlers. Safe to call multiple times.\n   */\n  installShutdownHooks(): void {\n    if (this.signalHandler !== undefined || this.closed) return;\n    const handler = (): void => {\n      void this.close();\n    };\n    this.signalHandler = handler;\n    process.once('SIGTERM', handler);\n    process.once('SIGINT', handler);\n  }\n\n  /** Count of events currently waiting to be sent. Useful for tests. */\n  get pendingCount(): number {\n    return this.queue.length;\n  }\n\n  // ── internals ─────────────────────────────────────────────────────────\n\n  private async send(batch: TelemetryEvent[]): Promise<void> {\n    const headers: Record<string, string> = {\n      'content-type': 'application/json',\n    };\n    if (this.apiKey) headers['authorization'] = `Bearer ${this.apiKey}`;\n    if (this.workspaceId) headers['x-workspace-id'] = this.workspaceId;\n\n    const controller = new AbortController();\n    const abortTimer = setTimeout(() => controller.abort(), FLUSH_TIMEOUT_MS);\n\n    try {\n      const res = await fetch(this.endpoint, {\n        method: 'POST',\n        headers,\n        body: JSON.stringify({ events: batch }),\n        signal: controller.signal,\n      });\n\n      if (!res.ok) {\n        const text = await safeReadBody(res);\n        throw new TelemetryHttpError(res.status, text);\n      }\n    } finally {\n      clearTimeout(abortTimer);\n    }\n  }\n\n  private startTimer(): void {\n    this.timer = setInterval(() => {\n      void this.flush();\n    }, this.flushIntervalMs);\n\n    // node-only: don't block process exit\n    (this.timer as { unref?: () => void }).unref?.();\n  }\n\n  private safeNotify(err: unknown): void {\n    try {\n      this.onError(err instanceof Error ? err : new Error(String(err)));\n    } catch {\n      // user-provided hook must never bubble up\n    }\n  }\n}\n\nexport class TelemetryHttpError extends Error {\n  constructor(\n    public readonly status: number,\n    public readonly responseBody: string,\n  ) {\n    super(`Telemetry ingest returned HTTP ${status}`);\n    this.name = 'TelemetryHttpError';\n  }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n  if (!Number.isFinite(value)) return min;\n  return Math.max(min, Math.min(max, Math.trunc(value)));\n}\n\nasync function safeReadBody(res: Response): Promise<string> {\n  try {\n    const text = await res.text();\n    return text.slice(0, 500);\n  } catch {\n    return '';\n  }\n}\n","/**\n * @module @arcis/node/utils/ip\n * Platform-aware client IP detection.\n *\n * Prevents IP spoofing by reading platform-specific headers\n * instead of blindly trusting X-Forwarded-For.\n *\n * @example\n * // Auto-detect platform from environment\n * const ip = detectClientIp(req);\n *\n * // Explicit platform\n * const ip = detectClientIp(req, { platform: 'cloudflare' });\n */\n\nimport type { IncomingMessage } from 'http';\n\nexport type Platform =\n  | 'auto'\n  | 'cloudflare'\n  | 'vercel'\n  | 'flyio'\n  | 'render'\n  | 'firebase'\n  | 'aws-alb'\n  | 'generic';\n\nexport interface DetectIpOptions {\n  /** Platform to use for header selection. Default: 'auto' */\n  platform?: Platform;\n  /** Number of trusted proxies (for X-Forwarded-For parsing). Default: 1 */\n  trustedProxyCount?: number;\n}\n\ninterface RequestLike {\n  headers: Record<string, string | string[] | undefined>;\n  socket?: { remoteAddress?: string };\n  connection?: { remoteAddress?: string };\n  ip?: string;\n}\n\n/**\n * Platform-specific header configurations.\n * Each platform sets a trusted header that cannot be spoofed by the client.\n */\nconst PLATFORM_HEADERS: Record<Exclude<Platform, 'auto' | 'generic'>, string> = {\n  cloudflare: 'cf-connecting-ip',\n  vercel: 'x-real-ip',\n  flyio: 'fly-client-ip',\n  render: 'x-render-client-ip',\n  firebase: 'x-appengine-user-ip',\n  'aws-alb': 'x-forwarded-for',\n};\n\n/**\n * Auto-detect the platform from environment variables.\n */\nfunction detectPlatform(): Platform {\n  const env = typeof process !== 'undefined' ? process.env : {};\n\n  if (env.CF_PAGES || env.CF_WORKERS) return 'cloudflare';\n  if (env.VERCEL) return 'vercel';\n  if (env.FLY_APP_NAME) return 'flyio';\n  if (env.RENDER) return 'render';\n  if (env.FIREBASE_CONFIG || env.GCLOUD_PROJECT) return 'firebase';\n  if (env.AWS_EXECUTION_ENV || env.AWS_LAMBDA_FUNCTION_NAME) return 'aws-alb';\n\n  return 'generic';\n}\n\n// Cache the detected platform — it won't change during process lifetime\nlet _cachedPlatform: Platform | null = null;\n\nfunction getCachedPlatform(): Platform {\n  if (_cachedPlatform === null) {\n    _cachedPlatform = detectPlatform();\n  }\n  return _cachedPlatform;\n}\n\n/** Max IP string length (IPv6 max = 45 chars) */\nconst MAX_IP_LENGTH = 45;\n\n/**\n * Sanitize an IP string: trim, truncate, strip control characters.\n * Prevents unbounded strings from being used as map keys.\n */\nfunction sanitizeIp(ip: string): string {\n  const trimmed = ip.trim();\n  if (trimmed.length > MAX_IP_LENGTH) return trimmed.slice(0, MAX_IP_LENGTH);\n  return trimmed;\n}\n\n/**\n * Get a header value from the request, handling string arrays.\n */\nfunction getHeader(req: RequestLike, name: string): string | undefined {\n  const val = req.headers[name];\n  if (Array.isArray(val)) return val[0];\n  return val;\n}\n\n/**\n * Parse the rightmost trusted IP from X-Forwarded-For.\n * Reading from the right prevents client spoofing — the rightmost entry\n * is the one added by the closest trusted proxy.\n */\nfunction parseForwardedFor(header: string, trustedProxyCount: number): string | undefined {\n  const ips = header.split(',').map(ip => ip.trim()).filter(Boolean);\n  if (ips.length === 0) return undefined;\n\n  // The client IP is at position (length - trustedProxyCount)\n  const clientIndex = Math.max(0, ips.length - trustedProxyCount);\n  return ips[clientIndex] || undefined;\n}\n\n/**\n * Detect the real client IP address from a request.\n *\n * Uses platform-specific headers when available to prevent IP spoofing.\n * Falls back to X-Forwarded-For (parsed from the right) and then\n * the socket remote address.\n *\n * @param req - HTTP request object (Express, raw http, etc.)\n * @param options - Detection options\n * @returns Client IP address, or 'unknown' if unresolvable\n *\n * @example\n * // Auto-detect platform\n * app.use((req, res, next) => {\n *   const clientIp = detectClientIp(req);\n *   console.log('Client IP:', clientIp);\n *   next();\n * });\n *\n * @example\n * // Behind Cloudflare\n * const ip = detectClientIp(req, { platform: 'cloudflare' });\n *\n * @example\n * // Behind 2 proxies (e.g. CDN + load balancer)\n * const ip = detectClientIp(req, { trustedProxyCount: 2 });\n */\nexport function detectClientIp(\n  req: RequestLike | IncomingMessage,\n  options: DetectIpOptions = {}\n): string {\n  const { platform = 'auto', trustedProxyCount = 1 } = options;\n  const r = req as RequestLike;\n\n  const resolvedPlatform = platform === 'auto' ? getCachedPlatform() : platform;\n\n  // 1. Try platform-specific header (most trusted)\n  if (resolvedPlatform !== 'generic' && resolvedPlatform in PLATFORM_HEADERS) {\n    const headerName = PLATFORM_HEADERS[resolvedPlatform as keyof typeof PLATFORM_HEADERS];\n    if (headerName) {\n      if (resolvedPlatform === 'aws-alb') {\n        // AWS ALB: parse X-Forwarded-For from the right\n        const xff = getHeader(r, 'x-forwarded-for');\n        if (xff) {\n          const ip = parseForwardedFor(xff, trustedProxyCount);\n          if (ip) return sanitizeIp(ip);\n        }\n      } else {\n        const ip = getHeader(r, headerName);\n        if (ip) return sanitizeIp(ip);\n      }\n    }\n  }\n\n  // 2. Try Express req.ip (respects trust proxy setting)\n  if (r.ip) return sanitizeIp(r.ip);\n\n  // 3. Try X-Forwarded-For (parsed from the right for safety)\n  const xff = getHeader(r, 'x-forwarded-for');\n  if (xff) {\n    const ip = parseForwardedFor(xff, trustedProxyCount);\n    if (ip) return sanitizeIp(ip);\n  }\n\n  // 4. Try X-Real-IP\n  const realIp = getHeader(r, 'x-real-ip');\n  if (realIp) return sanitizeIp(realIp);\n\n  // 5. Socket remote address\n  const socketIp = r.socket?.remoteAddress ?? r.connection?.remoteAddress;\n  if (socketIp) return sanitizeIp(socketIp);\n\n  return 'unknown';\n}\n\n/**\n * Check if an IP address is a private/internal address.\n *\n * Detects: loopback, private ranges (RFC 1918), link-local, IPv6 equivalents.\n */\nexport function isPrivateIp(ip: string): boolean {\n  // Strip IPv4-mapped IPv6 prefix (::ffff:127.0.0.1 -> 127.0.0.1)\n  const normalized = ip.startsWith('::ffff:') ? ip.slice(7) : ip;\n\n  // IPv4 private ranges\n  if (/^127\\./.test(normalized)) return true;                          // Loopback\n  if (/^10\\./.test(normalized)) return true;                           // Class A private\n  if (/^172\\.(1[6-9]|2\\d|3[01])\\./.test(normalized)) return true;     // Class B private\n  if (/^192\\.168\\./.test(normalized)) return true;                     // Class C private\n  if (/^169\\.254\\./.test(normalized)) return true;                     // Link-local\n  if (/^0\\./.test(normalized)) return true;                            // Current network\n\n  // IPv6\n  if (ip === '::1') return true;                               // Loopback\n  if (/^fe80:/i.test(ip)) return true;                         // Link-local\n  if (/^fc00:/i.test(ip)) return true;                         // Unique local\n  if (/^fd/i.test(ip)) return true;                            // Unique local\n\n  return false;\n}\n\n/** Reset cached platform (for testing). */\nexport function _resetPlatformCache(): void {\n  _cachedPlatform = null;\n}\n","/**\n * @module @arcis/node/intelligence/client\n * Cloud IP-reputation client with a local LRU+TTL cache.\n *\n * Design rules:\n *   1. `check()` is synchronous and never blocks the request path. On a cache\n *      miss it returns `found:false` for THIS request and schedules a\n *      background refresh, so the hot path adds ~0ms. Subsequent requests from\n *      the same IP read the cached verdict (Pattern: opportunistic refresh, not\n *      on the hot path).\n *   2. Fail-open (Pattern 4): a network error, timeout, or non-200 resolves to\n *      `found:false` and never throws into the request path.\n *   3. Private / loopback / unresolved IPs are never looked up.\n *   4. A \"not found\" (clean) result IS cached so clean IPs are not re-queried\n *      every request; transport errors are NOT cached so they retry.\n */\n\nimport { isPrivateIp } from '../utils/ip';\nimport type { IntelligenceOptions, IpReputation, BotCorpusEntry } from './types';\n\nconst DEFAULT_CACHE_MAX = 1000;\nconst DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour\nconst DEFAULT_TIMEOUT_MS = 2000;\nconst MIN_TIMEOUT_MS = 100;\n\ninterface CacheEntry {\n  value: IpReputation;\n  expires: number;\n}\n\n/** Insertion-ordered LRU with per-entry TTL. */\nclass LruTtlCache {\n  private readonly map = new Map<string, CacheEntry>();\n  constructor(\n    private readonly max: number,\n    private readonly ttlMs: number,\n  ) {}\n\n  get(key: string): IpReputation | undefined {\n    const entry = this.map.get(key);\n    if (!entry) return undefined;\n    if (Date.now() > entry.expires) {\n      this.map.delete(key);\n      return undefined;\n    }\n    // Mark most-recently-used by reinserting at the tail.\n    this.map.delete(key);\n    this.map.set(key, entry);\n    return entry.value;\n  }\n\n  set(key: string, value: IpReputation): void {\n    if (this.map.has(key)) this.map.delete(key);\n    this.map.set(key, { value, expires: Date.now() + this.ttlMs });\n    while (this.map.size > this.max) {\n      const oldest = this.map.keys().next().value;\n      if (oldest === undefined) break;\n      this.map.delete(oldest);\n    }\n  }\n\n  clear(): void {\n    this.map.clear();\n  }\n\n  get size(): number {\n    return this.map.size;\n  }\n}\n\ninterface RawReputation {\n  ip?: unknown;\n  found?: unknown;\n  severity?: unknown;\n  categories?: unknown;\n  sources?: unknown;\n  first_seen?: unknown;\n  last_seen?: unknown;\n  matched?: unknown;\n}\n\nfunction asStringArray(v: unknown): string[] | undefined {\n  if (!Array.isArray(v)) return undefined;\n  const out = v.filter((s): s is string => typeof s === 'string');\n  return out.length > 0 ? out : undefined;\n}\n\n/** Map the dashboard wire shape (snake_case) to the SDK result (camelCase). */\nfunction normalize(ip: string, body: RawReputation): IpReputation {\n  if (body.found !== true) return { ip, found: false };\n  const result: IpReputation = { ip, found: true };\n  if (typeof body.severity === 'number') result.severity = body.severity;\n  const categories = asStringArray(body.categories);\n  if (categories) result.categories = categories;\n  const sources = asStringArray(body.sources);\n  if (sources) result.sources = sources;\n  if (typeof body.first_seen === 'string') result.firstSeen = body.first_seen;\n  if (typeof body.last_seen === 'string') result.lastSeen = body.last_seen;\n  if (typeof body.matched === 'string') result.matched = body.matched;\n  return result;\n}\n\nfunction isBotCorpusEntry(v: unknown): v is BotCorpusEntry {\n  if (typeof v !== 'object' || v === null) return false;\n  const e = v as Record<string, unknown>;\n  return (\n    typeof e.id === 'string' &&\n    typeof e.category === 'string' &&\n    typeof e.name === 'string' &&\n    Array.isArray(e.patterns) &&\n    e.patterns.every((p) => typeof p === 'string') &&\n    Array.isArray(e.forbidden) &&\n    e.forbidden.every((p) => typeof p === 'string')\n  );\n}\n\nexport class IntelligenceClient {\n  private readonly base: string;\n  private readonly apiKey: string | undefined;\n  private readonly workspaceId: string | undefined;\n  private readonly timeoutMs: number;\n  private readonly ipRepEnabled: boolean;\n  private readonly onError: (err: Error) => void;\n  private readonly cache: LruTtlCache;\n  private readonly inFlight = new Set<string>();\n  private closed = false;\n\n  constructor(options: IntelligenceOptions) {\n    if (!options.endpoint || typeof options.endpoint !== 'string') {\n      throw new TypeError('IntelligenceClient: `endpoint` is required');\n    }\n    this.base = options.endpoint.replace(/\\/+$/, '');\n    this.apiKey = options.apiKey;\n    this.workspaceId = options.workspaceId;\n    this.timeoutMs = Math.max(MIN_TIMEOUT_MS, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n    this.ipRepEnabled = (options.cloudDecisions ?? []).includes('ip-rep');\n    this.onError = options.onError ?? (() => {\n      // default: swallow (fail-open)\n    });\n    this.cache = new LruTtlCache(\n      Math.max(1, options.cacheMax ?? DEFAULT_CACHE_MAX),\n      Math.max(1000, options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS),\n    );\n  }\n\n  /**\n   * Synchronous, cache-first reputation read. Never blocks: a cache miss\n   * returns `found:false` and schedules a background refresh so later requests\n   * from the same IP get the verdict. Safe to call on the hot path.\n   */\n  check(ip: string): IpReputation {\n    if (!this.ipRepEnabled || this.closed) return { ip, found: false };\n    if (!ip || ip === 'unknown' || isPrivateIp(ip)) return { ip, found: false };\n    const cached = this.cache.get(ip);\n    if (cached) return cached;\n    this.scheduleRefresh(ip);\n    return { ip, found: false };\n  }\n\n  /**\n   * Await a lookup and return the verdict. Fail-open: any transport error\n   * resolves to `found:false`. Used by direct callers and tests; the request\n   * path uses `check()` instead.\n   */\n  async lookup(ip: string): Promise<IpReputation> {\n    if (!ip || ip === 'unknown' || isPrivateIp(ip)) return { ip, found: false };\n    try {\n      return await this.fetchReputation(ip);\n    } catch (err) {\n      this.safeNotify(err);\n      return { ip, found: false };\n    }\n  }\n\n  /**\n   * Fetch the full bot corpus from the intelligence endpoint. Fail-open: any\n   * transport/parse error resolves to an empty array (the caller keeps the\n   * bundled corpus). Returns only well-formed entries.\n   */\n  async fetchBotCorpus(): Promise<BotCorpusEntry[]> {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n    try {\n      const headers: Record<string, string> = { accept: 'application/json' };\n      if (this.apiKey) headers['authorization'] = `Bearer ${this.apiKey}`;\n      if (this.workspaceId) headers['x-workspace-id'] = this.workspaceId;\n      const res = await fetch(`${this.base}/v1/intel/bot-corpus/snapshot`, {\n        headers,\n        signal: controller.signal,\n      });\n      if (!res.ok) throw new Error(`bot-corpus fetch returned HTTP ${res.status}`);\n      const body = (await res.json()) as { entries?: unknown };\n      if (!Array.isArray(body.entries)) return [];\n      return body.entries.filter(isBotCorpusEntry);\n    } catch (err) {\n      this.safeNotify(err);\n      return [];\n    } finally {\n      clearTimeout(timer);\n    }\n  }\n\n  /** Current number of cached entries. Useful for tests. */\n  get cacheSize(): number {\n    return this.cache.size;\n  }\n\n  /** Stop scheduling refreshes and drop the cache. Idempotent. */\n  close(): void {\n    this.closed = true;\n    this.cache.clear();\n    this.inFlight.clear();\n  }\n\n  // ── internals ───────────────────────────────────────────────────────────\n\n  private scheduleRefresh(ip: string): void {\n    if (this.inFlight.has(ip)) return;\n    this.inFlight.add(ip);\n    // Real results (including a clean \"not found\") are cached; transport\n    // errors are not, so they retry on the next request from this IP.\n    this.fetchReputation(ip)\n      .then((rep) => {\n        if (!this.closed) this.cache.set(ip, rep);\n      })\n      .catch((err) => this.safeNotify(err))\n      .finally(() => this.inFlight.delete(ip));\n  }\n\n  private async fetchReputation(ip: string): Promise<IpReputation> {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n    try {\n      const headers: Record<string, string> = { accept: 'application/json' };\n      if (this.apiKey) headers['authorization'] = `Bearer ${this.apiKey}`;\n      if (this.workspaceId) headers['x-workspace-id'] = this.workspaceId;\n      const url = `${this.base}/v1/intel/ip-reputation/${encodeURIComponent(ip)}`;\n      const res = await fetch(url, { headers, signal: controller.signal });\n      if (!res.ok) {\n        throw new Error(`ip-reputation lookup returned HTTP ${res.status}`);\n      }\n      const body = (await res.json()) as RawReputation;\n      return normalize(ip, body);\n    } finally {\n      clearTimeout(timer);\n    }\n  }\n\n  private safeNotify(err: unknown): void {\n    try {\n      this.onError(err instanceof Error ? err : new Error(String(err)));\n    } catch {\n      // user hook must never bubble up\n    }\n  }\n}\n\n/** Map a numeric reputation severity (1-10) to a coarse telemetry severity. */\nexport function reputationSeverityTier(\n  severity: number | undefined,\n): 'critical' | 'high' | 'medium' | 'low' {\n  const s = severity ?? 0;\n  if (s >= 9) return 'critical';\n  if (s >= 7) return 'high';\n  if (s >= 4) return 'medium';\n  return 'low';\n}\n","/**\n * @module @arcis/node/middleware/main\n * Main arcis() middleware factory\n */\n\nimport type { Request, RequestHandler, Response, NextFunction } from 'express';\nimport type {\n  ArcisOptions,\n  ArcisFunction,\n  ArcisMiddlewareStack,\n  HeaderOptions,\n  RateLimitOptions,\n  SanitizeEvent,\n  SanitizeOptions,\n} from '../core/types';\nimport { createHeaders } from './headers';\nimport { createRateLimiter } from './rate-limit';\nimport { createErrorHandler } from './error-handler';\nimport { createTelemetryEmitter, tapSanitizerThreats } from './telemetry';\nimport { botProtection, mergeBotPatterns, type BotProtectionOptions } from './bot-detection';\nimport { scannerPathProtection, type ScannerPathsOptions } from './sensitive-paths';\nimport { inspectGraphqlQuery, type GraphqlGuardOptions } from '../sanitizers/graphql';\nimport { detectMassAssignment, type MassAssignDetectOptions } from '../sanitizers/mass-assignment';\nimport { scanForSsrf, type ValidateUrlOptions } from '../validation/url';\nimport { detectPromptInjection, type PromptInjectionSeverity } from '../sanitizers/prompt-injection';\nimport { createSanitizer, scanThreats } from '../sanitizers';\nimport { validate } from '../validation';\nimport { createSafeLogger } from '../logging';\nimport { TelemetryClient } from '../telemetry/client';\nimport type { TelemetryOptions } from '../telemetry/types';\nimport { IntelligenceClient, reputationSeverityTier } from '../intelligence/client';\nimport { detectClientIp } from '../utils/ip';\nimport type { IpReputation, IntelligenceOptions, CloudDecision } from '../intelligence/types';\n\n/**\n * Resolve cloud-intelligence config from in-code options or `ARCIS_INTEL_*`\n * env vars. The env fallback lets 12-factor apps turn on cloud intelligence\n * with no code change (mirrors the telemetry env pickup). In-code options win\n * when an endpoint is set both ways.\n *\n *   ARCIS_INTEL_ENDPOINT   required to activate the env path\n *   ARCIS_INTEL_KEY        optional bearer token\n *   ARCIS_INTEL_WORKSPACE        optional workspace id\n *   ARCIS_INTEL_DECISIONS        comma list: \"ip-rep,bot-corpus\"\n *   ARCIS_INTEL_BLOCK_THRESHOLD  optional int; reputation severity at/above\n *                                which to block (omit = annotate only)\n */\nfunction resolveIntelligenceOptions(opt?: IntelligenceOptions): IntelligenceOptions | undefined {\n  if (opt?.endpoint) return opt;\n  const endpoint = process.env.ARCIS_INTEL_ENDPOINT;\n  if (!endpoint) return undefined;\n  const valid: CloudDecision[] = ['ip-rep', 'bot-corpus'];\n  const cloudDecisions = (process.env.ARCIS_INTEL_DECISIONS ?? '')\n    .split(',')\n    .map((s) => s.trim())\n    .filter((s): s is CloudDecision => (valid as string[]).includes(s));\n  const rawThreshold = process.env.ARCIS_INTEL_BLOCK_THRESHOLD;\n  const blockThreshold =\n    rawThreshold && Number.isFinite(Number(rawThreshold)) ? Number(rawThreshold) : undefined;\n  return {\n    endpoint,\n    apiKey: process.env.ARCIS_INTEL_KEY,\n    workspaceId: process.env.ARCIS_INTEL_WORKSPACE,\n    cloudDecisions,\n    blockThreshold,\n  };\n}\n\ndeclare module 'express-serve-static-core' {\n  interface Request {\n    /** IP reputation verdict attached by the intelligence middleware, when enabled. */\n    arcisIpReputation?: IpReputation;\n  }\n}\n\n/**\n * Build TelemetryOptions from `ARCIS_*` environment variables when the user\n * didn't pass `telemetry` in `arcis({...})`. Returns undefined if `ARCIS_ENDPOINT`\n * isn't set — preserving zero-overhead opt-in.\n *\n * Recognized env vars:\n *   - `ARCIS_ENDPOINT`           (required to activate)\n *   - `ARCIS_WORKSPACE_ID`       (optional; sent as x-workspace-id)\n *   - `ARCIS_KEY`                (optional; sent as Authorization: Bearer <key>)\n *   - `ARCIS_BATCH_SIZE`         (optional integer; default 50)\n *   - `ARCIS_FLUSH_INTERVAL_MS`  (optional integer; default 5000)\n *\n * Explicit `options.telemetry` always wins over env. This preserves the\n * existing opt-in contract and lets callers override env in tests.\n */\nfunction buildTelemetryFromEnv(): TelemetryOptions | undefined {\n  const env = typeof process !== 'undefined' ? process.env : undefined;\n  const endpoint = env?.ARCIS_ENDPOINT;\n  if (!endpoint) return undefined;\n  const opts: TelemetryOptions = { endpoint };\n  if (env?.ARCIS_WORKSPACE_ID) opts.workspaceId = env.ARCIS_WORKSPACE_ID;\n  if (env?.ARCIS_KEY) opts.apiKey = env.ARCIS_KEY;\n  const batch = env?.ARCIS_BATCH_SIZE ? parseInt(env.ARCIS_BATCH_SIZE, 10) : NaN;\n  if (!Number.isNaN(batch)) opts.batchSize = batch;\n  const flush = env?.ARCIS_FLUSH_INTERVAL_MS ? parseInt(env.ARCIS_FLUSH_INTERVAL_MS, 10) : NaN;\n  if (!Number.isNaN(flush)) opts.flushIntervalMs = flush;\n  return opts;\n}\n\n/**\n * Create Arcis middleware with all protections enabled.\n * \n * @param options - Configuration options\n * @returns Array of Express middleware\n * \n * @example\n * // Full protection (recommended)\n * app.use(arcis());\n * \n * @example\n * // Custom configuration\n * app.use(arcis({\n *   rateLimit: { max: 50 },\n *   headers: { frameOptions: 'SAMEORIGIN' }\n * }));\n * \n * @example\n * // Disable specific features\n * app.use(arcis({\n *   rateLimit: false,\n *   sanitize: { sql: false }\n * }));\n * \n * @example\n * // Cleanup on shutdown\n * const middleware = arcis();\n * app.use(middleware);\n * process.on('SIGTERM', () => middleware.close());\n */\n/**\n * Issue #47 — observer middleware. Pre-scans `req.body / req.query /\n * req.params / req.path` for threats and fires `onSanitize` for each hit.\n * Always calls `next()` (no blocking, no mutation) — control flow is\n * owned by the rate-limit and sanitizer middlewares downstream.\n *\n * Errors thrown from the user callback are caught and swallowed so a\n * buggy observer can't take down the request path.\n */\nfunction createSanitizeObserver(\n  onSanitize: (event: SanitizeEvent) => void,\n): RequestHandler {\n  return (req: Request, _res: Response, next: NextFunction) => {\n    const fields: ReadonlyArray<readonly [string, unknown]> = [\n      ['body', req.body],\n      ['query', req.query],\n      ['params', req.params],\n      ['path', req.path],\n    ];\n    for (const [name, value] of fields) {\n      const hit = scanThreats(value);\n      if (!hit) continue;\n      try {\n        onSanitize({\n          type: hit.vector,\n          field: name,\n          original: hit.matchedPattern,\n          pattern: hit.matchedPattern,\n        });\n      } catch {\n        // Observer must never break the response — fail-open.\n      }\n    }\n    next();\n  };\n}\n\n/**\n * Issue #47 — wraps a 429-emitting middleware so the response body is\n * suppressed in dry-run mode. The X-RateLimit-* headers the limiter set\n * BEFORE deciding to 429 still flow through (they were attached to the\n * response Header map by the limiter), giving observability without\n * actually blocking the request.\n *\n * The rate-limit middleware's 429 path is `res.status(429).json({...})`\n * followed by an early return (no `next()` call). To suppress, we\n * intercept `res.status` and on 429:\n *   - flag `suppressed`,\n *   - swallow the chained `.json(...)` (no body write),\n *   - restore the originals,\n *   - call `next()` ourselves so the rest of the middleware stack runs.\n *\n * This is monkey-patching with a tightly-scoped lifetime — restored\n * the moment we hand control downstream so no other middleware sees\n * the patched methods.\n */\nfunction suppressRateLimit429(handler: RequestHandler): RequestHandler {\n  return (req, res, next) => {\n    const originalStatus = res.status.bind(res);\n    const originalJson = res.json.bind(res);\n    let suppressed = false;\n    let nextCalled = false;\n\n    const restore = (): void => {\n      res.status = originalStatus;\n      res.json = originalJson;\n    };\n\n    res.status = ((code: number): Response => {\n      if (code === 429) {\n        suppressed = true;\n        return res; // chainable; the .json below no-ops.\n      }\n      return originalStatus(code);\n    }) as Response['status'];\n\n    res.json = ((body: unknown): Response => {\n      if (suppressed) {\n        // Limiter's 429 path: it called .status(429).json(...) and then\n        // returned without next(). Hand control to the rest of the chain\n        // ourselves. Restore originals first so downstream sees a clean\n        // ResponseWriter.\n        restore();\n        if (!nextCalled) {\n          nextCalled = true;\n          next();\n        }\n        return res;\n      }\n      return originalJson(body);\n    }) as Response['json'];\n\n    handler(req, res, (err) => {\n      // Allow path: handler called next() itself. Restore methods so\n      // downstream middleware operates on the unwrapped response.\n      restore();\n      if (!nextCalled) {\n        nextCalled = true;\n        next(err);\n      }\n    });\n  };\n}\n\nexport function arcis(options: ArcisOptions = {}): ArcisMiddlewareStack {\n  const middlewares: RequestHandler[] = [];\n  const cleanupFns: (() => void)[] = [];\n  const dryRun = options.dryRun === true;\n\n  // Telemetry emitter — first, so latency includes the full middleware chain.\n  // Opt-in: zero overhead unless options.telemetry.endpoint is set, OR\n  // ARCIS_ENDPOINT is present in the environment. Explicit options win.\n  let telemetryClient: TelemetryClient | undefined;\n  const telemetryOpts = options.telemetry?.endpoint\n    ? options.telemetry\n    : buildTelemetryFromEnv();\n  if (telemetryOpts) {\n    const client = new TelemetryClient(telemetryOpts);\n    telemetryClient = client;\n    middlewares.push(createTelemetryEmitter(client));\n    cleanupFns.push(() => {\n      void client.close();\n    });\n  }\n\n  // Security headers (always before rate-limit/sanitize)\n  if (options.headers !== false) {\n    const headerOpts: HeaderOptions = typeof options.headers === 'object'\n      ? options.headers\n      : {};\n    middlewares.push(createHeaders(headerOpts));\n  }\n\n  // Scanner-path probe blocking (v1.7 W2). Runs BEFORE bot detection because\n  // some scanner UAs forge a browser UA but still hit dotfile / WordPress\n  // probe paths. Dry-run skips the block.\n  if (options.scannerPaths !== false && !dryRun) {\n    const scannerOpts: ScannerPathsOptions = typeof options.scannerPaths === 'object'\n      ? options.scannerPaths\n      : {};\n    middlewares.push(scannerPathProtection(scannerOpts));\n  }\n\n  // Forwarded-header inspection (v1.7 W7). Flags a loopback address in a\n  // forwarded / client-IP header (spoofing to bypass IP allowlists), and\n  // optionally rejects Host / X-Forwarded-Host not in a trustedHosts\n  // allowlist. Runs early (header read, no body needed). Skipped in dry-run.\n  if (options.forwardedHeaders !== false && !dryRun) {\n    const FORWARDED = ['x-forwarded-for', 'x-forwarded-host', 'x-real-ip', 'forwarded', 'client-ip', 'true-client-ip'];\n    const LOOPBACK = /(?:^|[\\s,@=])(?:127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|::1|0\\.0\\.0\\.0|localhost)(?::\\d+)?(?:$|[\\s,;])/i;\n    const trustedHosts = typeof options.forwardedHeaders === 'object' && options.forwardedHeaders.trustedHosts\n      ? options.forwardedHeaders.trustedHosts.map((h) => h.toLowerCase())\n      : null;\n    middlewares.push((req, res, next): void => {\n      for (const name of FORWARDED) {\n        const raw = req.headers[name];\n        const value = Array.isArray(raw) ? raw.join(',') : raw;\n        if (typeof value === 'string' && LOOPBACK.test(value)) {\n          res.status(403).json({\n            error: 'Request blocked for security reasons',\n            code: 'SECURITY_THREAT',\n            vector: 'header',\n            rule: 'header/forwarded-loopback-spoof',\n          });\n          return;\n        }\n      }\n      if (trustedHosts) {\n        for (const name of ['host', 'x-forwarded-host']) {\n          const raw = req.headers[name];\n          const value = Array.isArray(raw) ? raw[0] : raw;\n          if (typeof value === 'string' && value) {\n            const host = value.split(':')[0].toLowerCase();\n            if (!trustedHosts.includes(host)) {\n              res.status(403).json({\n                error: 'Request blocked for security reasons',\n                code: 'SECURITY_THREAT',\n                vector: 'header',\n                rule: 'header/untrusted-host',\n              });\n              return;\n            }\n          }\n        }\n      }\n      next();\n    });\n  }\n\n  // Cloud intelligence (opt-in). One client serves both capabilities; created\n  // when an endpoint is set and cloudDecisions names at least one.\n  const intel = resolveIntelligenceOptions(options.intelligence);\n  const intelDecisions = intel?.endpoint ? intel.cloudDecisions ?? [] : [];\n  if (intelDecisions.length > 0 && intel) {\n    const intelClient = new IntelligenceClient(intel);\n    cleanupFns.push(() => intelClient.close());\n\n    // Bot-corpus cloud refresh: fetch on startup + on an interval, merging the\n    // curated additions on top of the bundled corpus so new scanners / AI\n    // crawlers are classified without an SDK release. Fail-open: fetchBotCorpus\n    // returns [] on any error, so the bundled corpus is never disturbed.\n    if (intelDecisions.includes('bot-corpus')) {\n      const refresh = (): void => {\n        void intelClient.fetchBotCorpus().then((entries) => {\n          if (entries.length > 0) mergeBotPatterns(entries);\n        });\n      };\n      refresh();\n      const refreshMs = Math.max(\n        60_000,\n        intel.botCorpusRefreshMs ?? 7 * 24 * 60 * 60 * 1000,\n      );\n      const timer = setInterval(refresh, refreshMs);\n      (timer as { unref?: () => void }).unref?.();\n      cleanupFns.push(() => clearInterval(timer));\n    }\n\n    // Cloud IP reputation per-request lookup. Runs early (IP-level, no body\n    // needed), after forwarded-header inspection and before bot/rate-limit so a\n    // known-bad IP is blocked before consuming quota. Cache-first and\n    // non-blocking: a miss never adds latency, and an unreachable service fails\n    // open.\n    if (intelDecisions.includes('ip-rep')) {\n      const blockThreshold = intel.blockThreshold;\n      middlewares.push((req, res, next): void => {\n        const ip = detectClientIp(req);\n        const rep = intelClient.check(ip);\n        req.arcisIpReputation = rep;\n        const shouldBlock =\n          !dryRun &&\n          rep.found &&\n          typeof blockThreshold === 'number' &&\n          (rep.severity ?? 0) >= blockThreshold;\n        if (shouldBlock) {\n          req.__arcis = {\n            vector: 'ip-reputation',\n            rule: 'ip-reputation/known-bad',\n            severity: reputationSeverityTier(rep.severity),\n            reason: `IP reputation severity ${rep.severity} >= ${blockThreshold}`,\n            decision: 'deny',\n          };\n          res.status(403).json({\n            error: 'Request blocked for security reasons',\n            code: 'SECURITY_THREAT',\n            vector: 'ip-reputation',\n            rule: 'ip-reputation/known-bad',\n          });\n          return;\n        }\n        next();\n      });\n    }\n  }\n\n  // Bot UA classification — runs BEFORE rate-limit so bots don't consume\n  // legitimate-traffic rate-limit quota. v1.7 W1 wire-up (was opt-in via\n  // standalone botProtection() factory; now default-on). Dry-run mode skips\n  // the deny step (detection still attaches result to req.botDetection) so\n  // dashboards can see \"would have blocked\" decisions.\n  if (options.bot !== false) {\n    const userBotOpts: BotProtectionOptions = typeof options.bot === 'object'\n      ? options.bot\n      : {};\n    const botOpts: BotProtectionOptions = {\n      // Default deny: AUTOMATED (headless browser automation: Selenium /\n      // Puppeteer / Playwright / PhantomJS / WebDriver / Headless Chrome) and\n      // SECURITY_SCANNER (offensive scanners: sqlmap / nikto / nuclei / nmap /\n      // masscan / wpscan / Acunetix / Nessus / dirbuster). SCRAPER is NOT\n      // default-denied: it also covers curl / wget / python-requests /\n      // monitoring and other legitimate non-browser clients, so blocking it by\n      // default would break health checks and server-to-server traffic. Add it\n      // explicitly with arcis({ bot: { deny: ['AUTOMATED', 'SCRAPER'] } }).\n      deny: userBotOpts.deny ?? ['AUTOMATED', 'SECURITY_SCANNER'],\n      allow: userBotOpts.allow,\n      defaultAction: userBotOpts.defaultAction,\n      statusCode: userBotOpts.statusCode,\n      message: userBotOpts.message,\n      detectBehavior: userBotOpts.detectBehavior,\n      onDetected: userBotOpts.onDetected,\n    };\n    if (dryRun) {\n      // Dry-run: classify + attach to req for observation, but never deny.\n      const classifyOnly: BotProtectionOptions = {\n        ...botOpts,\n        deny: [],\n        defaultAction: 'allow',\n      };\n      middlewares.push(botProtection(classifyOnly));\n    } else {\n      middlewares.push(botProtection(botOpts));\n    }\n  }\n\n  // Issue #47 — observer pre-scan. Sits BEFORE the rate-limit + sanitizer so\n  // the callback fires on every request that contains a threat, not just\n  // those that survive rate-limiting. Skipped when no callback is set so\n  // the default zero-overhead path is preserved.\n  if (options.onSanitize) {\n    middlewares.push(createSanitizeObserver(options.onSanitize));\n  }\n\n  // Rate limiting — emitter detects 429 from response status, no wrap needed.\n  // Dry-run wraps the limiter so the limiter's 429 decision is silently\n  // dropped (headers still set; request continues). X-RateLimit-* headers\n  // surface either way so dashboards see the would-have-been decision.\n  if (options.rateLimit !== false) {\n    const rateLimitOpts: RateLimitOptions = typeof options.rateLimit === 'object'\n      ? options.rateLimit\n      : {};\n    const rateLimiter = createRateLimiter(rateLimitOpts);\n    middlewares.push(dryRun ? suppressRateLimit429(rateLimiter) : rateLimiter);\n    cleanupFns.push(() => rateLimiter.close());\n  }\n\n  // GraphQL inspection (v1.7 W3). When the JSON body has a `query`\n  // field, treat it as a GraphQL document and run the inspector. Sits\n  // between rate-limit and sanitizer so the depth/alias-bomb check\n  // happens BEFORE the regex-heavy body sanitizer chews on it. Skipped\n  // in dry-run mode.\n  if (options.graphql !== false && !dryRun) {\n    const userGqlOpts: GraphqlGuardOptions = typeof options.graphql === 'object'\n      ? options.graphql\n      : {};\n    // Tighter defaults than the standalone factory: 12-alias bombs\n    // bypass the standalone default of 50, and most legit queries\n    // never need >10 aliases. Users running Apollo Studio in dev\n    // pass blockIntrospection: false explicitly.\n    const gqlOpts: GraphqlGuardOptions = {\n      maxDepth: userGqlOpts.maxDepth ?? 10,\n      maxLength: userGqlOpts.maxLength ?? 10000,\n      blockIntrospection: userGqlOpts.blockIntrospection ?? true,\n      maxAliases: userGqlOpts.maxAliases ?? 10,\n      blockFragmentCycles: userGqlOpts.blockFragmentCycles ?? true,\n    };\n    middlewares.push((req, res, next) => {\n      const body = req.body as Record<string, unknown> | undefined;\n      const query = body && typeof body === 'object' ? body.query : undefined;\n      if (typeof query !== 'string' || query.length === 0) {\n        return next();\n      }\n      const result = inspectGraphqlQuery(query, gqlOpts);\n      if (!result.blocked) {\n        return next();\n      }\n      res.status(403).json({\n        error: 'Request blocked for security reasons',\n        code: 'SECURITY_THREAT',\n        vector: 'graphql',\n        rule: `graphql/${result.reason}`,\n      });\n    });\n  }\n\n  // Mass-assignment field detection (v1.7 W4). Scan the JSON body for\n  // privilege-escalation field names. Runs after GraphQL (cheap key walk\n  // vs the GraphQL string parse) and before the sanitizer. Skipped in\n  // dry-run.\n  if (options.massAssign !== false && !dryRun) {\n    const massAssignOpts: MassAssignDetectOptions = typeof options.massAssign === 'object'\n      ? options.massAssign\n      : {};\n    middlewares.push((req, res, next) => {\n      const result = detectMassAssignment(req.body, massAssignOpts);\n      if (!result.detected) {\n        return next();\n      }\n      res.status(403).json({\n        error: 'Request blocked for security reasons',\n        code: 'SECURITY_THREAT',\n        vector: 'mass-assignment',\n        rule: 'mass-assignment/sensitive-field',\n      });\n    });\n  }\n\n  // SSRF body-URL validation (v1.7 W5). Walk the JSON body for URL-shaped\n  // strings and validate each. Skipped in dry-run.\n  if (options.ssrf !== false && !dryRun) {\n    const ssrfOpts: ValidateUrlOptions = typeof options.ssrf === 'object'\n      ? options.ssrf\n      : {};\n    middlewares.push((req, res, next) => {\n      const result = scanForSsrf(req.body, ssrfOpts);\n      if (!result.detected) {\n        return next();\n      }\n      res.status(403).json({\n        error: 'Request blocked for security reasons',\n        code: 'SECURITY_THREAT',\n        vector: 'ssrf',\n        rule: 'ssrf/blocked-url',\n      });\n    });\n  }\n\n  // Prompt-injection detection on body strings (v1.7 W6). Walk the JSON\n  // body for string values and run the prompt-injection detector; block\n  // when a match at or above the configured severity is found. Skipped\n  // in dry-run.\n  if (options.promptInjection !== false && !dryRun) {\n    const piRank: Record<string, number> = { none: 0, low: 1, medium: 2, high: 3 };\n    const minSeverity: PromptInjectionSeverity =\n      typeof options.promptInjection === 'object' && options.promptInjection.minSeverity\n        ? options.promptInjection.minSeverity\n        : 'medium';\n    const minRank = piRank[minSeverity];\n    const scanPromptInjection = (value: unknown, depth: number): boolean => {\n      if (depth > 8 || value === null) return false;\n      if (typeof value === 'string') {\n        const r = detectPromptInjection(value);\n        return r.detected && piRank[r.severity] >= minRank;\n      }\n      if (typeof value !== 'object') return false;\n      if (Array.isArray(value)) {\n        return value.some((v) => scanPromptInjection(v, depth + 1));\n      }\n      return Object.values(value as Record<string, unknown>).some((v) =>\n        scanPromptInjection(v, depth + 1),\n      );\n    };\n    middlewares.push((req, res, next) => {\n      if (!scanPromptInjection(req.body, 0)) {\n        return next();\n      }\n      res.status(403).json({\n        error: 'Request blocked for security reasons',\n        code: 'SECURITY_THREAT',\n        vector: 'prompt-injection',\n        rule: 'prompt-injection/detected',\n      });\n    });\n  }\n\n  // Input sanitization — wrap with telemetry tap so SecurityThreatError\n  // populates req.__arcis with vector/rule/severity for the emitter.\n  // Dry-run forces block: false so the sanitizer can never short-circuit\n  // with a 403; detection still happens via the observer above.\n  if (options.sanitize !== false) {\n    const sanitizeOpts: SanitizeOptions = typeof options.sanitize === 'object'\n      ? { ...options.sanitize }\n      : {};\n    if (options.block && sanitizeOpts.block === undefined) {\n      sanitizeOpts.block = true;\n    }\n    if (dryRun) {\n      sanitizeOpts.block = false;\n    }\n    const sanitizer = createSanitizer(sanitizeOpts);\n    middlewares.push(telemetryClient ? tapSanitizerThreats(sanitizer) : sanitizer);\n  }\n\n  // Attach close() directly on the array so callers can clean up without any-casts.\n  const result = middlewares as ArcisMiddlewareStack;\n  result.close = () => {\n    for (const fn of cleanupFns) {\n      fn();\n    }\n  };\n\n  return result;\n}\n\n// Attach individual functions for granular use\nconst arcisWithMethods = arcis as ArcisFunction;\narcisWithMethods.sanitize = createSanitizer;\narcisWithMethods.rateLimit = createRateLimiter;\narcisWithMethods.headers = createHeaders;\narcisWithMethods.validate = validate;\narcisWithMethods.logger = createSafeLogger;\narcisWithMethods.errorHandler = createErrorHandler;\n\nexport { arcisWithMethods as arcisFunction };\nexport default arcisWithMethods;\n","/**\n * @module @arcis/node/nestjs\n *\n * NestJS adapter for Arcis.\n *\n * Two ways to wire this up:\n *\n * 1. Global functional middleware (zero NestJS knowledge required):\n *    ```ts\n *    // main.ts\n *    import { NestFactory } from '@nestjs/core';\n *    import { arcis } from '@arcis/node';\n *    const app = await NestFactory.create(AppModule);\n *    app.use(arcis({ block: true }));\n *    ```\n *\n * 2. DI-aware module + class middleware (per-route control):\n *    ```ts\n *    // app.module.ts\n *    import { Module, MiddlewareConsumer, NestModule } from '@nestjs/common';\n *    import { ArcisModule, ArcisMiddleware } from '@arcis/node/nestjs';\n *\n *    @Module({ imports: [ArcisModule.forRoot({ block: true })] })\n *    export class AppModule implements NestModule {\n *      configure(consumer: MiddlewareConsumer) {\n *        consumer.apply(ArcisMiddleware).forRoutes('*');\n *      }\n *    }\n *    ```\n *\n * No runtime dependency on `@nestjs/common`: the only NestJS reference is a\n * type-only import erased at compile time. NestJS users already have\n * `@nestjs/common` installed; non-NestJS users pay nothing.\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { CanActivate, DynamicModule, ExecutionContext } from '@nestjs/common';\nimport { arcis } from './main';\nimport type { ArcisOptions, ArcisMiddlewareStack } from '../core/types';\n\n/** Injection token for `ArcisOptions` consumed by `ArcisMiddleware`'s factory. */\nexport const ARCIS_OPTIONS = Symbol('ARCIS_OPTIONS');\n\n/**\n * NestJS-compatible class middleware. Implements the structural shape NestJS\n * expects (`.use(req, res, next)`) without importing `NestMiddleware` at\n * runtime. Internally builds the same handler stack as `arcis()` and walks it\n * sequentially, propagating errors and short-circuit responses correctly.\n */\nexport class ArcisMiddleware {\n  private readonly handlers: ArcisMiddlewareStack;\n\n  constructor(options: ArcisOptions = {}) {\n    this.handlers = arcis(options);\n  }\n\n  use(req: Request, res: Response, next: NextFunction): void {\n    const handlers = this.handlers;\n    let i = 0;\n    const run = (err?: unknown): void => {\n      if (err !== undefined) {\n        next(err as Parameters<NextFunction>[0]);\n        return;\n      }\n      const handler: RequestHandler | undefined = handlers[i++];\n      if (!handler) {\n        next();\n        return;\n      }\n      try {\n        handler(req, res, run);\n      } catch (caught) {\n        next(caught as Parameters<NextFunction>[0]);\n      }\n    };\n    run();\n  }\n\n  /** Release rate-limiter intervals etc. Call from `OnApplicationShutdown`. */\n  close(): void {\n    this.handlers.close();\n  }\n}\n\n/**\n * NestJS Guard implementation of the Arcis stack.\n *\n * Class-middleware applied via `MiddlewareConsumer.apply().forRoutes()` does\n * not reliably short-circuit NestJS's controller pipeline when an inner\n * handler writes `res.status(403).end()` without calling Express's `next`.\n * The controller resolution path runs anyway and the controller's return\n * value overwrites the deny response. CI surfaced this with 0-of-8 attacks\n * blocked on the NestJS example using the `MiddlewareConsumer` pattern.\n *\n * `CanActivate` runs in the correct NestJS lifecycle slot (after body-parse,\n * before controller resolution) and is designed to deny via `return false`\n * or by writing the response directly. When an Arcis handler writes a 403,\n * the guard sees `res.headersSent === true` after it runs and returns\n * `false`, which NestJS treats as a denial without re-running the\n * controller. Successful traversal (no threats found) returns `true` and\n * NestJS proceeds to the controller with the mutated (sanitized) req.\n *\n * Recommended over `ArcisMiddleware` for NestJS apps that want deny-on-\n * detect behavior. `ArcisMiddleware` is retained for backward compat but\n * is best suited for sanitize-only / observation-only usage.\n *\n * Register globally via the `APP_GUARD` token:\n *\n * ```ts\n * import { APP_GUARD } from '@nestjs/core';\n * import { ArcisGuard } from '@arcis/node/nestjs';\n *\n * @Module({\n *   providers: [\n *     {\n *       provide: APP_GUARD,\n *       useFactory: () => new ArcisGuard({ block: true }),\n *     },\n *   ],\n * })\n * export class AppModule {}\n * ```\n */\nexport class ArcisGuard implements CanActivate {\n  private readonly handlers: ArcisMiddlewareStack;\n\n  constructor(options: ArcisOptions = {}) {\n    this.handlers = arcis(options);\n  }\n\n  canActivate(context: ExecutionContext): Promise<boolean> {\n    const http = context.switchToHttp();\n    const req = http.getRequest<Request>();\n    const res = http.getResponse<Response>();\n\n    return new Promise((resolve, reject) => {\n      const handlers = this.handlers;\n      let i = 0;\n      const run = (err?: unknown): void => {\n        if (err !== undefined) {\n          reject(err as Error);\n          return;\n        }\n        if (res.headersSent) {\n          // A prior handler wrote a terminal response (the sanitizer's\n          // 403 or the limiter's 429). NestJS sees headersSent === true\n          // and lets the response pass through; returning false denies\n          // controller resolution.\n          resolve(false);\n          return;\n        }\n        const handler: RequestHandler | undefined = handlers[i++];\n        if (!handler) {\n          resolve(!res.headersSent);\n          return;\n        }\n        let advanced = false;\n        const wrappedNext = (innerErr?: unknown): void => {\n          advanced = true;\n          run(innerErr);\n        };\n        try {\n          handler(req, res, wrappedNext);\n        } catch (caught) {\n          reject(caught as Error);\n          return;\n        }\n        // Synchronous-handler post-check: the sanitizer / rate limiter\n        // write res.status(...).json(...) and return without calling\n        // next. After handler() returns, if next wasn't called but the\n        // response was already written, the chain ended right here and\n        // we can resolve immediately. Async handlers (that haven't\n        // resolved yet) leave `advanced` false and `headersSent` false,\n        // and we wait for them to call wrappedNext on their own.\n        if (!advanced && res.headersSent) {\n          resolve(false);\n        }\n      };\n      run();\n    });\n  }\n\n  /** Release rate-limiter intervals etc. Call from `OnApplicationShutdown`. */\n  close(): void {\n    this.handlers.close();\n  }\n}\n\n/**\n * NestJS dynamic module. `ArcisModule.forRoot(options)` is the entry point.\n * Returns a plain `DynamicModule` literal so `@Module({})` is unnecessary on\n * `ArcisModule` itself; this keeps `@nestjs/common` purely a type-only import.\n *\n * Exports both `ArcisMiddleware` (for legacy `MiddlewareConsumer` consumers)\n * and `ArcisGuard` (recommended; actually denies attacks on detect).\n */\nexport class ArcisModule {\n  static forRoot(options: ArcisOptions = {}): DynamicModule {\n    return {\n      module: ArcisModule,\n      providers: [\n        { provide: ARCIS_OPTIONS, useValue: options },\n        {\n          provide: ArcisMiddleware,\n          useFactory: (opts: ArcisOptions) => new ArcisMiddleware(opts),\n          inject: [ARCIS_OPTIONS],\n        },\n        {\n          provide: ArcisGuard,\n          useFactory: (opts: ArcisOptions) => new ArcisGuard(opts),\n          inject: [ARCIS_OPTIONS],\n        },\n      ],\n      exports: [ArcisMiddleware, ArcisGuard],\n    };\n  }\n}\n\nexport default ArcisModule;\n"]}