agent-threat-rules 4.1.5 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/CHANGELOG.md +751 -1
  2. package/README.md +356 -125
  3. package/dist/adapters/openshell-filter.d.ts +10 -3
  4. package/dist/adapters/openshell-filter.d.ts.map +1 -1
  5. package/dist/adapters/openshell-filter.js +10 -3
  6. package/dist/adapters/openshell-filter.js.map +1 -1
  7. package/dist/adapters/stdio-adapter.js +3 -3
  8. package/dist/adapters/stdio-adapter.js.map +1 -1
  9. package/dist/cli/mcp-tools-document.d.ts +40 -0
  10. package/dist/cli/mcp-tools-document.d.ts.map +1 -0
  11. package/dist/cli/mcp-tools-document.js +95 -0
  12. package/dist/cli/mcp-tools-document.js.map +1 -0
  13. package/dist/cli/scan-handler.d.ts +8 -0
  14. package/dist/cli/scan-handler.d.ts.map +1 -1
  15. package/dist/cli/scan-handler.js +126 -34
  16. package/dist/cli/scan-handler.js.map +1 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +80 -43
  19. package/dist/cli.js.map +1 -1
  20. package/dist/converters/sarif.d.ts +14 -2
  21. package/dist/converters/sarif.d.ts.map +1 -1
  22. package/dist/converters/sarif.js +7 -9
  23. package/dist/converters/sarif.js.map +1 -1
  24. package/dist/corpus-event.d.ts +47 -5
  25. package/dist/corpus-event.d.ts.map +1 -1
  26. package/dist/corpus-event.js +68 -29
  27. package/dist/corpus-event.js.map +1 -1
  28. package/dist/embedding/model-loader.d.ts +2 -0
  29. package/dist/embedding/model-loader.d.ts.map +1 -1
  30. package/dist/embedding/model-loader.js +3 -1
  31. package/dist/embedding/model-loader.js.map +1 -1
  32. package/dist/enforcement.d.ts +8 -0
  33. package/dist/enforcement.d.ts.map +1 -1
  34. package/dist/enforcement.js +10 -0
  35. package/dist/enforcement.js.map +1 -1
  36. package/dist/engine.d.ts +150 -6
  37. package/dist/engine.d.ts.map +1 -1
  38. package/dist/engine.js +337 -76
  39. package/dist/engine.js.map +1 -1
  40. package/dist/eval/embedding-provenance.d.ts +40 -0
  41. package/dist/eval/embedding-provenance.d.ts.map +1 -0
  42. package/dist/eval/embedding-provenance.js +71 -0
  43. package/dist/eval/embedding-provenance.js.map +1 -0
  44. package/dist/eval/eval-harness.d.ts +34 -0
  45. package/dist/eval/eval-harness.d.ts.map +1 -1
  46. package/dist/eval/eval-harness.js +49 -2
  47. package/dist/eval/eval-harness.js.map +1 -1
  48. package/dist/eval/hackaprompt-corpus.d.ts +12 -0
  49. package/dist/eval/hackaprompt-corpus.d.ts.map +1 -1
  50. package/dist/eval/hackaprompt-corpus.js +15 -1
  51. package/dist/eval/hackaprompt-corpus.js.map +1 -1
  52. package/dist/eval/hackaprompt-provenance.d.ts +52 -0
  53. package/dist/eval/hackaprompt-provenance.d.ts.map +1 -0
  54. package/dist/eval/hackaprompt-provenance.js +108 -0
  55. package/dist/eval/hackaprompt-provenance.js.map +1 -0
  56. package/dist/eval/run-hackaprompt-benchmark.d.ts +18 -8
  57. package/dist/eval/run-hackaprompt-benchmark.d.ts.map +1 -1
  58. package/dist/eval/run-hackaprompt-benchmark.js +154 -64
  59. package/dist/eval/run-hackaprompt-benchmark.js.map +1 -1
  60. package/dist/eval/run-pint-benchmark.js +11 -1
  61. package/dist/eval/run-pint-benchmark.js.map +1 -1
  62. package/dist/eval/skill-benchmark.d.ts +26 -6
  63. package/dist/eval/skill-benchmark.d.ts.map +1 -1
  64. package/dist/eval/skill-benchmark.js +49 -16
  65. package/dist/eval/skill-benchmark.js.map +1 -1
  66. package/dist/flywheel.d.ts +4 -0
  67. package/dist/flywheel.d.ts.map +1 -1
  68. package/dist/flywheel.js +12 -4
  69. package/dist/flywheel.js.map +1 -1
  70. package/dist/hook-handler.d.ts +11 -1
  71. package/dist/hook-handler.d.ts.map +1 -1
  72. package/dist/hook-handler.js +84 -16
  73. package/dist/hook-handler.js.map +1 -1
  74. package/dist/hook-tool-output.d.ts +47 -0
  75. package/dist/hook-tool-output.d.ts.map +1 -0
  76. package/dist/hook-tool-output.js +110 -0
  77. package/dist/hook-tool-output.js.map +1 -0
  78. package/dist/index.d.ts +5 -3
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +3 -2
  81. package/dist/index.js.map +1 -1
  82. package/dist/layer-integration.d.ts +4 -2
  83. package/dist/layer-integration.d.ts.map +1 -1
  84. package/dist/layer-integration.js +6 -2
  85. package/dist/layer-integration.js.map +1 -1
  86. package/dist/mcp-server.d.ts +8 -0
  87. package/dist/mcp-server.d.ts.map +1 -1
  88. package/dist/mcp-server.js +1 -0
  89. package/dist/mcp-server.js.map +1 -1
  90. package/dist/mcp-tools/scan.d.ts.map +1 -1
  91. package/dist/mcp-tools/scan.js +9 -1
  92. package/dist/mcp-tools/scan.js.map +1 -1
  93. package/dist/measurement/enforce-lane.d.ts +66 -0
  94. package/dist/measurement/enforce-lane.d.ts.map +1 -0
  95. package/dist/measurement/enforce-lane.js +89 -0
  96. package/dist/measurement/enforce-lane.js.map +1 -0
  97. package/dist/measurement/from-eval-harness.d.ts +16 -3
  98. package/dist/measurement/from-eval-harness.d.ts.map +1 -1
  99. package/dist/measurement/from-eval-harness.js +15 -5
  100. package/dist/measurement/from-eval-harness.js.map +1 -1
  101. package/dist/measurement/in-sample-ablation.d.ts +29 -0
  102. package/dist/measurement/in-sample-ablation.d.ts.map +1 -0
  103. package/dist/measurement/in-sample-ablation.js +45 -0
  104. package/dist/measurement/in-sample-ablation.js.map +1 -0
  105. package/dist/measurement/schema.d.ts +38 -1
  106. package/dist/measurement/schema.d.ts.map +1 -1
  107. package/dist/measurement/schema.js +43 -1
  108. package/dist/measurement/schema.js.map +1 -1
  109. package/dist/quality/action-eligibility.d.ts +4 -2
  110. package/dist/quality/action-eligibility.d.ts.map +1 -1
  111. package/dist/quality/action-eligibility.js.map +1 -1
  112. package/dist/rule-confidence.d.ts +31 -0
  113. package/dist/rule-confidence.d.ts.map +1 -0
  114. package/dist/rule-confidence.js +49 -0
  115. package/dist/rule-confidence.js.map +1 -0
  116. package/dist/rule-scaffolder.d.ts.map +1 -1
  117. package/dist/rule-scaffolder.js +43 -4
  118. package/dist/rule-scaffolder.js.map +1 -1
  119. package/dist/semantic-evaluator.d.ts.map +1 -1
  120. package/dist/semantic-evaluator.js +15 -13
  121. package/dist/semantic-evaluator.js.map +1 -1
  122. package/dist/shadow-evaluator.d.ts +7 -2
  123. package/dist/shadow-evaluator.d.ts.map +1 -1
  124. package/dist/shadow-evaluator.js +29 -25
  125. package/dist/shadow-evaluator.js.map +1 -1
  126. package/dist/testcase-event.d.ts +82 -1
  127. package/dist/testcase-event.d.ts.map +1 -1
  128. package/dist/testcase-event.js +135 -16
  129. package/dist/testcase-event.js.map +1 -1
  130. package/dist/tier0-invariant.d.ts.map +1 -1
  131. package/dist/tier0-invariant.js +1 -0
  132. package/dist/tier0-invariant.js.map +1 -1
  133. package/dist/tier1-blacklist.d.ts.map +1 -1
  134. package/dist/tier1-blacklist.js +1 -0
  135. package/dist/tier1-blacklist.js.map +1 -1
  136. package/dist/tool-definition-scope.d.ts +45 -0
  137. package/dist/tool-definition-scope.d.ts.map +1 -0
  138. package/dist/tool-definition-scope.js +68 -0
  139. package/dist/tool-definition-scope.js.map +1 -0
  140. package/dist/types.d.ts +42 -2
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/verdict.d.ts +46 -2
  143. package/dist/verdict.d.ts.map +1 -1
  144. package/dist/verdict.js +99 -14
  145. package/dist/verdict.js.map +1 -1
  146. package/package.json +2 -1
  147. package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +2 -2
  148. package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +1 -1
  149. package/rules/agent-manipulation/ATR-2026-00328-named-mode-persona-override.yaml +1 -1
  150. package/rules/agent-manipulation/ATR-2026-00330-yoja-allcaps-settings-block-persona.yaml +1 -1
  151. package/rules/agent-manipulation/ATR-2026-00418-weknora-mcp-config-rce.yaml +5 -5
  152. package/rules/agent-manipulation/ATR-2026-00432-superagi-output-handler-eval-rce.yaml +1 -1
  153. package/rules/agent-manipulation/ATR-2026-00440-semantic-kernel-vector-store-eval-rce.yaml +3 -3
  154. package/rules/context-exfiltration/ATR-2026-00426-nl-output-injection-credential-leak.yaml +1 -1
  155. package/rules/context-exfiltration/ATR-2026-00501-data-exfiltration-via-markdown-image-and-link-url-injection.yaml +16 -2
  156. package/rules/context-exfiltration/ATR-2026-00505-system-prompt-extraction-instruction-dump-request.yaml +6 -4
  157. package/rules/context-exfiltration/ATR-2026-00702-ipi-credential-exfil-via-agent-action.yaml +1 -1
  158. package/rules/context-exfiltration/ATR-2026-00707-ipi-file-exfil-with-destroy-or-tamper.yaml +1 -1
  159. package/rules/context-exfiltration/ATR-2026-00851-indirect-pi-financial-payment-exfil.yaml +1 -1
  160. package/rules/context-exfiltration/ATR-2026-01457-sysprompt-completion-clone-attack.yaml +1 -1
  161. package/rules/context-exfiltration/ATR-2026-01462-sysprompt-override-pseudo-admin.yaml +1 -1
  162. package/rules/context-exfiltration/ATR-2026-01463-imend-imsystem-prompt-injection-format.yaml +1 -1
  163. package/rules/context-exfiltration/ATR-2026-01606-ssrf-internal-network-scan.yaml +1 -1
  164. package/rules/context-exfiltration/ATR-2026-02847-policy-justified-exfil-to-email.yaml +1 -1
  165. package/rules/context-exfiltration/ATR-2026-02855-cross-email-exfil-relay.yaml +79 -0
  166. package/rules/context-exfiltration/ATR-2026-02861-exfil-send-email-with-body-directive.yaml +83 -0
  167. package/rules/context-exfiltration/ATR-2026-02866-idna-label-separator-in-fetch-url-host.yaml +104 -0
  168. package/rules/excessive-autonomy/ATR-2026-00500-ssrf-via-agent-url-fetch-instruction.yaml +12 -2
  169. package/rules/excessive-autonomy/ATR-2026-00710-ipi-physical-access-grant.yaml +1 -1
  170. package/rules/model-abuse/ATR-2026-01897-host-sabotage.yaml +2 -2
  171. package/rules/model-security/ATR-2026-00433-modelcache-torch-load-deserialization-rce.yaml +1 -1
  172. package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +1 -1
  173. package/rules/privilege-escalation/ATR-2026-00436-enclave-vm-sandbox-escape-rce.yaml +1 -1
  174. package/rules/privilege-escalation/ATR-2026-01601-sql-injection-destructive-ddl.yaml +3 -3
  175. package/rules/privilege-escalation/ATR-2026-01612-debug-mode-privilege-escalation.yaml +1 -1
  176. package/rules/privilege-escalation/ATR-2026-02867-identifier-typed-tool-argument-dot-dot-path-segment.yaml +106 -0
  177. package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +2 -2
  178. package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +1 -1
  179. package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +1 -1
  180. package/rules/prompt-injection/ATR-2026-00203-context-pollution-skill-description.yaml +1 -1
  181. package/rules/prompt-injection/ATR-2026-00228-structured-jailbreak.yaml +2 -2
  182. package/rules/prompt-injection/ATR-2026-00233-structured-jailbreak.yaml +2 -2
  183. package/rules/prompt-injection/ATR-2026-00256-base-n-encoding-jailbreak.yaml +1 -1
  184. package/rules/prompt-injection/ATR-2026-00264-latent-injection-translation.yaml +3 -3
  185. package/rules/prompt-injection/ATR-2026-00265-latent-injection-rag-document.yaml +1 -1
  186. package/rules/prompt-injection/ATR-2026-00282-perez-prompt-injection-hijack.yaml +4 -4
  187. package/rules/prompt-injection/ATR-2026-00321-hyphenated-system-instruction-injection.yaml +1 -1
  188. package/rules/prompt-injection/ATR-2026-00394-backspace-deletion-character-injection.yaml +2 -2
  189. package/rules/prompt-injection/ATR-2026-00446-variable-assignment-payload-injection.yaml +3 -3
  190. package/rules/prompt-injection/ATR-2026-00476-garak-web-injection-javascript-alert-1.yaml +3 -3
  191. package/rules/prompt-injection/ATR-2026-00481-garak-dan-mixedunassigned.yaml +1 -1
  192. package/rules/prompt-injection/ATR-2026-00489-garak-encoding-javascript-alert-1.yaml +3 -3
  193. package/rules/prompt-injection/ATR-2026-00503-fake-error-state-takeover-unrestricted-replacement-bot.yaml +4 -2
  194. package/rules/prompt-injection/ATR-2026-00508-escape-delimiter-wrapped-goal-hijacking-in-user-input-prompt.yaml +3 -3
  195. package/rules/prompt-injection/ATR-2026-00512-rules-file-backdoor-injection.yaml +1 -1
  196. package/rules/prompt-injection/ATR-2026-01005-many-shot-repetition-override.yaml +2 -2
  197. package/rules/prompt-injection/ATR-2026-01006-payload-split-string-concat-injection.yaml +2 -2
  198. package/rules/prompt-injection/ATR-2026-01015-evasion-refusal-suppression.yaml +1 -1
  199. package/rules/prompt-injection/ATR-2026-01016-evasion-response-priming-forced-opener.yaml +1 -1
  200. package/rules/prompt-injection/ATR-2026-01026-evasion-unicode-glitch-token-anomaly.yaml +2 -2
  201. package/rules/prompt-injection/ATR-2026-01304-indirect-injection-carrier-important-override.yaml +1 -1
  202. package/rules/prompt-injection/ATR-2026-01759-dos-new-important-instructions-injection-in-document.yaml +1 -1
  203. package/rules/prompt-injection/ATR-2026-01865-llmail-fake-email-boundary-marker.yaml +1 -1
  204. package/rules/prompt-injection/ATR-2026-02010-emoji-only-payload.yaml +2 -2
  205. package/rules/prompt-injection/ATR-2026-02815-injected-halt-order-canned-reply-dos.yaml +80 -0
  206. package/rules/prompt-injection/ATR-2026-02820-tool-result-orders-agent-to-hide-its-own-action.yaml +106 -0
  207. package/rules/prompt-injection/ATR-2026-02858-context-suppression-directive.yaml +73 -0
  208. package/rules/prompt-injection/ATR-2026-02859-tool-output-agent-role-reassignment.yaml +71 -0
  209. package/rules/prompt-injection/ATR-2026-02860-forged-instruction-boundary-marker.yaml +70 -0
  210. package/rules/prompt-injection/ATR-2026-02862-fake-chat-template-turn-injection.yaml +79 -0
  211. package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +1 -1
  212. package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +2 -2
  213. package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +1 -1
  214. package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +2 -2
  215. package/rules/skill-compromise/ATR-2026-00149-skill-exfil-compound.yaml +6 -6
  216. package/rules/skill-compromise/ATR-2026-00223-reverse-shell-dropper.yaml +2 -2
  217. package/rules/skill-compromise/ATR-2026-01755-backdoor-pot-linguistic-trigger-phrase.yaml +1 -1
  218. package/rules/skill-compromise/ATR-2026-01756-backdoor-pot-symbol-emoticon-trigger.yaml +1 -1
  219. package/rules/skill-compromise/ATR-2026-02261-code-credential-exfil-chain.yaml +1 -1
  220. package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +23 -23
  221. package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +16 -5
  222. package/rules/tool-poisoning/ATR-2026-00161-important-tag-cross-tool-shadowing.yaml +1 -1
  223. package/rules/tool-poisoning/ATR-2026-00277-echo-template-command-injection.yaml +2 -2
  224. package/rules/tool-poisoning/ATR-2026-00494-garak-exploitation-mixedunassigned.yaml +4 -4
  225. package/rules/tool-poisoning/ATR-2026-00521-shell-command-injection-agent-tool-context.yaml +1 -1
  226. package/rules/tool-poisoning/ATR-2026-00581-mcp-tool-rug-pull-post-approval-redefinition.yaml +1 -1
  227. package/rules/tool-poisoning/ATR-2026-01303-tool-schema-enumeration-social-engineering.yaml +1 -1
  228. package/rules/tool-poisoning/ATR-2026-01307-mcp-dns-rebinding-attack.yaml +2 -2
  229. package/rules/tool-poisoning/ATR-2026-01775-semantic-mcp-tool-manifest-poisoning.yaml +1 -1
  230. package/rules/tool-poisoning/ATR-2026-01932-shadow-undeclared-mcp-server-registration.yaml +1 -1
  231. package/rules/tool-poisoning/ATR-2026-02025-mcp-full-schema-poisoning-nondescription-field.yaml +1 -1
  232. package/rules/tool-poisoning/ATR-2026-02817-untrusted-content-dictates-tool-arguments.yaml +83 -0
  233. package/rules/tool-poisoning/ATR-2026-02864-non-canonical-ipv4-host-in-url-tool-argument.yaml +102 -0
  234. package/rules/tool-poisoning/ATR-2026-02865-read-only-utility-write-flag-in-command-argument.yaml +157 -0
  235. package/rules/tool-poisoning/ATR-2026-02868-ssrf-ipv6-transition-address-embedded-private-ipv4.yaml +107 -0
  236. package/rules/tool-poisoning/ATR-2026-02870-invisible-control-before-directive.yaml +94 -0
  237. package/spec/README.md +6 -3
  238. package/spec/atr-event-v1.0.md +13 -8
  239. package/spec/atr-method-v1.1.md +2 -2
  240. package/spec/category-registry/gemara/README.md +102 -0
  241. package/spec/category-registry/gemara/ai-agent-capability-catalog.yaml +157 -0
  242. package/spec/category-registry/gemara/atr-attack-vector-catalog.yaml +130 -0
  243. package/spec/category-registry/gemara/atr-detection-control-catalog.yaml +327 -0
  244. package/spec/category-registry/gemara/atr-threat-catalog.yaml +246 -0
  245. package/spec/category-registry/gemara/src/editorial.yaml +743 -0
  246. package/spec/mappings/README.md +1 -1
  247. package/spec/mappings/atr-to-nist-csf-2.0.md +5 -4
  248. package/spec/schema/event.schema.json +1 -1
@@ -3,7 +3,10 @@
3
3
  *
4
4
  * Implements the external content-filter contract proposed in
5
5
  * NVIDIA/OpenShell#1272 ("L7 content inspection hooks — scriptable
6
- * request/response filtering"): the OpenShell *supervisor* (outside the agent
6
+ * request/response filtering"). That proposal was closed as not planned on
7
+ * 2026-06-11 (OpenShell's maintainers pointed to their middleware RFC,
8
+ * NVIDIA/OpenShell#1733), so no OpenShell release runs this filter. The
9
+ * contract: the OpenShell *supervisor* (outside the agent
7
10
  * sandbox) runs this as a script against L7 request/response bodies. The body
8
11
  * arrives on stdin; the script signals the verdict via exit code:
9
12
  *
@@ -13,10 +16,14 @@
13
16
  *
14
17
  * Two run modes:
15
18
  * one-shot (default): read the whole body from stdin, evaluate, exit.
16
- * Matches the #1272 contract literally. Cold-starts the engine per call.
19
+ * Matches the #1272 contract literally. Cold-starts the engine per call:
20
+ * starting Node, loading the rule set and compiling its patterns take
21
+ * hundreds of milliseconds to about a second.
17
22
  * serve (--serve): read NDJSON requests line-by-line from stdin and write
18
23
  * one NDJSON verdict per line. Loads the rule set ONCE, so per-request
19
- * latency is just regex evaluation (sub-ms). Production path for a
24
+ * latency is just regex evaluation: a median of about a millisecond for
25
+ * a short body, tens of milliseconds for a multi-kilobyte one
26
+ * (scripts/bench-evaluate-latency.ts). Intended path for a
20
27
  * persistent guard service (cf. NVIDIA/OpenShell#1733 RFC 0005). A bad
21
28
  * line (or an engine error) yields a per-line error verdict and the
22
29
  * stream continues — one malformed body cannot take the inspector offline.
@@ -1 +1 @@
1
- {"version":3,"file":"openshell-filter.d.ts","sourceRoot":"","sources":["../../src/adapters/openshell-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAMH,qFAAqF;AACrF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/C,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAmBxC,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CACvC;AAmCD;;;GAGG;AACH,qBAAa,eAAe;IAKd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,WAAW,CAAgC;gBAEtB,OAAO,EAAE,aAAa;IAKnD,kEAAkE;IAClE,OAAO,CAAC,YAAY;IAKpB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CAmBpD;AAID,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAGjE;AAOD,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CAUrE"}
1
+ {"version":3,"file":"openshell-filter.d.ts","sourceRoot":"","sources":["../../src/adapters/openshell-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAMH,qFAAqF;AACrF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/C,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAmBxC,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CACvC;AAmCD;;;GAGG;AACH,qBAAa,eAAe;IAKd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,WAAW,CAAgC;gBAEtB,OAAO,EAAE,aAAa;IAKnD,kEAAkE;IAClE,OAAO,CAAC,YAAY;IAKpB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;CAmBpD;AAID,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAGjE;AAOD,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CAUrE"}
@@ -3,7 +3,10 @@
3
3
  *
4
4
  * Implements the external content-filter contract proposed in
5
5
  * NVIDIA/OpenShell#1272 ("L7 content inspection hooks — scriptable
6
- * request/response filtering"): the OpenShell *supervisor* (outside the agent
6
+ * request/response filtering"). That proposal was closed as not planned on
7
+ * 2026-06-11 (OpenShell's maintainers pointed to their middleware RFC,
8
+ * NVIDIA/OpenShell#1733), so no OpenShell release runs this filter. The
9
+ * contract: the OpenShell *supervisor* (outside the agent
7
10
  * sandbox) runs this as a script against L7 request/response bodies. The body
8
11
  * arrives on stdin; the script signals the verdict via exit code:
9
12
  *
@@ -13,10 +16,14 @@
13
16
  *
14
17
  * Two run modes:
15
18
  * one-shot (default): read the whole body from stdin, evaluate, exit.
16
- * Matches the #1272 contract literally. Cold-starts the engine per call.
19
+ * Matches the #1272 contract literally. Cold-starts the engine per call:
20
+ * starting Node, loading the rule set and compiling its patterns take
21
+ * hundreds of milliseconds to about a second.
17
22
  * serve (--serve): read NDJSON requests line-by-line from stdin and write
18
23
  * one NDJSON verdict per line. Loads the rule set ONCE, so per-request
19
- * latency is just regex evaluation (sub-ms). Production path for a
24
+ * latency is just regex evaluation: a median of about a millisecond for
25
+ * a short body, tens of milliseconds for a multi-kilobyte one
26
+ * (scripts/bench-evaluate-latency.ts). Intended path for a
20
27
  * persistent guard service (cf. NVIDIA/OpenShell#1733 RFC 0005). A bad
21
28
  * line (or an engine error) yields a per-line error verdict and the
22
29
  * stream continues — one malformed body cannot take the inspector offline.
@@ -1 +1 @@
1
- {"version":3,"file":"openshell-filter.js","sourceRoot":"","sources":["../../src/adapters/openshell-filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openshell-filter.js","sourceRoot":"","sources":["../../src/adapters/openshell-filter.ts"],"names":[],"mappings":"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"}
@@ -75,7 +75,7 @@ export class StdioAdapter {
75
75
  async alert(ctx) {
76
76
  const alertMsg = {
77
77
  type: "alert",
78
- severity: ctx.verdict.highestSeverity,
78
+ severity: ctx.verdict.highestSeverity ?? ctx.verdict.advisorySeverity ?? null,
79
79
  reason: ctx.verdict.reason,
80
80
  matchCount: ctx.verdict.matchCount,
81
81
  };
@@ -89,7 +89,7 @@ export class StdioAdapter {
89
89
  if (process.env.ATR_SHADOW_LOG) {
90
90
  const shadowMsg = {
91
91
  type: "shadow",
92
- severity: ctx.verdict.highestSeverity,
92
+ severity: ctx.verdict.highestSeverity ?? ctx.verdict.advisorySeverity ?? null,
93
93
  reason: ctx.verdict.reason,
94
94
  matchCount: ctx.verdict.matchCount,
95
95
  ruleIds: ctx.matches.map((m) => m.rule.id),
@@ -116,7 +116,7 @@ export class StdioAdapter {
116
116
  async escalate(ctx) {
117
117
  const escalation = {
118
118
  type: "escalation",
119
- severity: ctx.verdict.highestSeverity,
119
+ severity: ctx.verdict.highestSeverity ?? ctx.verdict.advisorySeverity ?? null,
120
120
  reason: ctx.verdict.reason,
121
121
  matchCount: ctx.verdict.matchCount,
122
122
  };
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-adapter.js","sourceRoot":"","sources":["../../src/adapters/stdio-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stdio-adapter.js","sourceRoot":"","sources":["../../src/adapters/stdio-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * An MCP `tools/list` document is a list of tool definitions, not an event.
3
+ *
4
+ * `atr scan tools.json` on `{"tools":[{"name":"add","description":"...","inputSchema":{...}}]}`
5
+ * — or on the JSON-RPC response `{"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}` — used to
6
+ * wrap the document as one event, find no `content` on it, skip it, and report
7
+ * "nothing was scanned". That is the input a tool-poisoning check most often starts from.
8
+ *
9
+ * Each tool becomes its own `mcp_exchange` event:
10
+ * - `content` is the tool definition as JSON, the whole object. It carries the name, the
11
+ * description and the input schema, including per-parameter descriptions, extra property
12
+ * fields, `required` and defaults: every one of those reaches the model, and the
13
+ * full-schema-poisoning rules anchor on the schema structure (`inputSchema`, `properties`).
14
+ * - `fields.tool_name` is the tool's name and `fields.tool_description` its top-level
15
+ * description, for the rules that read those fields. They are set only when the definition
16
+ * carries them as strings, never filled with something else.
17
+ * One event per tool keeps a finding attributable to a tool name.
18
+ *
19
+ * The CLI scans these events on an engine constructed with `toolDefinitions: true`, so the rules
20
+ * written for a tool being called do not run on them (src/tool-definition-scope.ts).
21
+ *
22
+ * @module agent-threat-rules/cli/mcp-tools-document
23
+ */
24
+ import type { AgentEvent } from '../types.js';
25
+ type JsonObject = Record<string, unknown>;
26
+ /** One mcp_exchange event for one tool definition. */
27
+ export declare function toolDefinitionToEvent(tool: JsonObject, timestamp: string): AgentEvent;
28
+ /**
29
+ * Events for a `tools/list` document, or null when the input is not one.
30
+ *
31
+ * Accepted: `{"tools":[...]}`, `{"result":{"tools":[...]}}` (a JSON-RPC response), and a
32
+ * non-empty JSON array whose every element is one of those (a log of several responses).
33
+ * A document that lists no tools yields an empty array, so the caller reports that nothing
34
+ * was scanned instead of a clean result. A tools entry that is not an object yields an event
35
+ * with no content, which the caller counts as skipped. An object that is already an event (string
36
+ * content, or an event type) is never read as a tools/list document, tools array or not.
37
+ */
38
+ export declare function toolsDocumentToEvents(parsed: unknown): AgentEvent[] | null;
39
+ export {};
40
+ //# sourceMappingURL=mcp-tools-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools-document.d.ts","sourceRoot":"","sources":["../../src/cli/mcp-tools-document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAoC1C,sDAAsD;AACtD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAarF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,EAAE,GAAG,IAAI,CAc1E"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * An MCP `tools/list` document is a list of tool definitions, not an event.
3
+ *
4
+ * `atr scan tools.json` on `{"tools":[{"name":"add","description":"...","inputSchema":{...}}]}`
5
+ * — or on the JSON-RPC response `{"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}` — used to
6
+ * wrap the document as one event, find no `content` on it, skip it, and report
7
+ * "nothing was scanned". That is the input a tool-poisoning check most often starts from.
8
+ *
9
+ * Each tool becomes its own `mcp_exchange` event:
10
+ * - `content` is the tool definition as JSON, the whole object. It carries the name, the
11
+ * description and the input schema, including per-parameter descriptions, extra property
12
+ * fields, `required` and defaults: every one of those reaches the model, and the
13
+ * full-schema-poisoning rules anchor on the schema structure (`inputSchema`, `properties`).
14
+ * - `fields.tool_name` is the tool's name and `fields.tool_description` its top-level
15
+ * description, for the rules that read those fields. They are set only when the definition
16
+ * carries them as strings, never filled with something else.
17
+ * One event per tool keeps a finding attributable to a tool name.
18
+ *
19
+ * The CLI scans these events on an engine constructed with `toolDefinitions: true`, so the rules
20
+ * written for a tool being called do not run on them (src/tool-definition-scope.ts).
21
+ *
22
+ * @module agent-threat-rules/cli/mcp-tools-document
23
+ */
24
+ function isObject(value) {
25
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
26
+ }
27
+ /** Event types an AgentEvent carries (src/types.ts AgentEvent['type']). */
28
+ const EVENT_TYPES = new Set([
29
+ 'llm_input',
30
+ 'llm_output',
31
+ 'tool_call',
32
+ 'tool_response',
33
+ 'mcp_exchange',
34
+ 'agent_behavior',
35
+ 'multi_agent_message',
36
+ ]);
37
+ /**
38
+ * An object that is already an event: string `content`, or a `type` that is an event type. Such an
39
+ * object stays on the event path even when it also carries a `tools` array (an LLM request logged
40
+ * with its tool list, for example): reading it as a tools/list document would drop its content.
41
+ */
42
+ function looksLikeEvent(doc) {
43
+ return typeof doc['content'] === 'string' || (typeof doc['type'] === 'string' && EVENT_TYPES.has(doc['type']));
44
+ }
45
+ /** The tools array of a `tools/list` result, bare or inside a JSON-RPC envelope; else null. */
46
+ function toolsArrayOf(doc) {
47
+ if (!isObject(doc))
48
+ return null;
49
+ if (looksLikeEvent(doc))
50
+ return null;
51
+ if (Array.isArray(doc['tools']))
52
+ return doc['tools'];
53
+ const result = doc['result'];
54
+ if (isObject(result) && Array.isArray(result['tools']))
55
+ return result['tools'];
56
+ return null;
57
+ }
58
+ /** One mcp_exchange event for one tool definition. */
59
+ export function toolDefinitionToEvent(tool, timestamp) {
60
+ const name = tool['name'];
61
+ const description = tool['description'];
62
+ const fields = {
63
+ ...(typeof name === 'string' && name !== '' ? { tool_name: name } : {}),
64
+ ...(typeof description === 'string' && description !== '' ? { tool_description: description } : {}),
65
+ };
66
+ return {
67
+ type: 'mcp_exchange',
68
+ timestamp,
69
+ content: JSON.stringify(tool),
70
+ ...(Object.keys(fields).length > 0 ? { fields } : {}),
71
+ };
72
+ }
73
+ /**
74
+ * Events for a `tools/list` document, or null when the input is not one.
75
+ *
76
+ * Accepted: `{"tools":[...]}`, `{"result":{"tools":[...]}}` (a JSON-RPC response), and a
77
+ * non-empty JSON array whose every element is one of those (a log of several responses).
78
+ * A document that lists no tools yields an empty array, so the caller reports that nothing
79
+ * was scanned instead of a clean result. A tools entry that is not an object yields an event
80
+ * with no content, which the caller counts as skipped. An object that is already an event (string
81
+ * content, or an event type) is never read as a tools/list document, tools array or not.
82
+ */
83
+ export function toolsDocumentToEvents(parsed) {
84
+ const documents = Array.isArray(parsed) ? parsed : [parsed];
85
+ if (documents.length === 0)
86
+ return null;
87
+ const toolLists = documents.map(toolsArrayOf);
88
+ if (toolLists.some((list) => list === null))
89
+ return null;
90
+ const timestamp = new Date().toISOString();
91
+ return toolLists.flatMap((tools) => tools.map((tool) => isObject(tool)
92
+ ? toolDefinitionToEvent(tool, timestamp)
93
+ : { type: 'mcp_exchange', timestamp, content: '' }));
94
+ }
95
+ //# sourceMappingURL=mcp-tools-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools-document.js","sourceRoot":"","sources":["../../src/cli/mcp-tools-document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,2EAA2E;AAC3E,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,WAAW;IACX,YAAY;IACZ,WAAW;IACX,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,qBAAqB;CACtB,CAAC,CAAC;AAEH;;;;GAIG;AACH,SAAS,cAAc,CAAC,GAAe;IACrC,OAAO,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjH,CAAC;AAED,+FAA+F;AAC/F,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,cAAc,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,qBAAqB,CAAC,IAAgB,EAAE,SAAiB;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,MAAM,GAA2B;QACrC,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpG,CAAC;IACF,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,SAAS;QACT,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,OAAQ,SAAyB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAClD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAc,EAAE,CAC7B,QAAQ,CAAC,IAAI,CAAC;QACZ,CAAC,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC;QACxC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CACrD,CACF,CAAC;AACJ,CAAC"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { ScanType } from '../types.js';
8
8
  import type { Lane } from '../quality/rule-contract.js';
9
+ import { type ModelDecisions } from '../verdict.js';
9
10
  export interface ScanOptions {
10
11
  readonly rules?: string;
11
12
  readonly json?: boolean;
@@ -21,6 +22,13 @@ export interface ScanOptions {
21
22
  readonly semanticModel?: string;
22
23
  readonly semanticTimeout?: string;
23
24
  readonly semanticNoJsonMode?: boolean;
25
+ /**
26
+ * What a match a model decided (here, a semantic rule's judge) may do.
27
+ * 'advisory' (default): listed, marked, and not counted toward --fail-on, and
28
+ * written to SARIF at level note with properties.enforced false. 'enforce':
29
+ * counted and written like any match.
30
+ */
31
+ readonly modelDecisions?: ModelDecisions;
24
32
  /**
25
33
  * Detection lane (which rule maturities may fire). Undefined means the
26
34
  * engine's built-in default; `src/cli.ts` resolves `--lane` and `ATR_LANE`
@@ -1 +1 @@
1
- {"version":3,"file":"scan-handler.d.ts","sourceRoot":"","sources":["../../src/cli/scan-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAoC,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAsBxD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;CACtB;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CA0B5D;AAED,6FAA6F;AAC7F,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
1
+ {"version":3,"file":"scan-handler.d.ts","sourceRoot":"","sources":["../../src/cli/scan-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAoC,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAIxD,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAoBpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;CACtB;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CA0B5D;AAED,6FAA6F;AAC7F,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
@@ -10,6 +10,8 @@ import { ATREngine } from '../engine.js';
10
10
  import { scanResultToSARIF } from '../converters/sarif.js';
11
11
  import { createTCReporter, resolveTcUrl } from '../tc-reporter.js';
12
12
  import { createSemanticJudgeFromConfig } from './semantic-judge-config.js';
13
+ import { isModelDecided } from '../verdict.js';
14
+ import { toolsDocumentToEvents } from './mcp-tools-document.js';
13
15
  const SEVERITY_ORDER = ['informational', 'low', 'medium', 'high', 'critical'];
14
16
  // ANSI colors
15
17
  const RED = '\x1b[31m';
@@ -114,6 +116,36 @@ export async function cmdScanUnified(target, rulesDir, options) {
114
116
  }
115
117
  }
116
118
  // ── MCP Event Scan ─────────────────────────────────────────────
119
+ /**
120
+ * A `.mcp.json` is a configuration document, not an event.
121
+ *
122
+ * `atr scan .mcp.json` — the invocation the README shows — parsed the file, wrapped it as one
123
+ * event, found no `content` on it and skipped it, while the summary still said one event had been
124
+ * scanned. The rules never saw a single server, so a config that sets `NODE_OPTIONS` to a require
125
+ * payload came back as `threats_detected: 0` instead of as an error.
126
+ *
127
+ * Each server becomes its own event, with the config as its content, which is the shape the MCP
128
+ * rules evaluate (ATR-2026-02300, the rule written for exactly this `.mcp.json` env-block surface,
129
+ * fires on it — see tests/cli-mcp-config-scan.test.ts). One event per server also keeps a finding
130
+ * attributable to a server name.
131
+ */
132
+ function configDocumentToEvents(parsed) {
133
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
134
+ return null;
135
+ const servers = parsed.mcpServers;
136
+ if (!servers || typeof servers !== 'object' || Array.isArray(servers))
137
+ return null;
138
+ const timestamp = new Date().toISOString();
139
+ const events = [];
140
+ for (const [name, config] of Object.entries(servers)) {
141
+ events.push({
142
+ type: 'mcp_exchange',
143
+ timestamp,
144
+ content: JSON.stringify({ mcpServers: { [name]: config } }),
145
+ });
146
+ }
147
+ return events.length > 0 ? events : null;
148
+ }
117
149
  async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
118
150
  const fileStat = statSync(eventsPath);
119
151
  if (fileStat.size > 50 * 1024 * 1024) {
@@ -122,9 +154,18 @@ async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
122
154
  }
123
155
  const raw = readFileSync(eventsPath, 'utf-8');
124
156
  let events;
157
+ // Whether the input is a tools/list document: every event is then a tool definition, and the
158
+ // engine is told so (toolDefinitions), so the rules written for a tool being called do not run
159
+ // on it (src/tool-definition-scope.ts). Config documents and event files are scanned as before.
160
+ let toolDefinitions = false;
125
161
  try {
126
162
  const parsed = JSON.parse(raw);
127
- events = Array.isArray(parsed) ? parsed : [parsed];
163
+ // A config document becomes one event per server, a tools/list document one event per
164
+ // tool; every other input is unchanged.
165
+ const configEvents = configDocumentToEvents(parsed);
166
+ const toolEvents = configEvents === null ? toolsDocumentToEvents(parsed) : null;
167
+ toolDefinitions = toolEvents !== null;
168
+ events = configEvents ?? toolEvents ?? (Array.isArray(parsed) ? parsed : [parsed]);
128
169
  }
129
170
  catch {
130
171
  console.error(`${RED}Error: Invalid JSON in ${eventsPath}${RESET}`);
@@ -136,7 +177,10 @@ async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
136
177
  reporter,
137
178
  semanticJudge: semantic.judge,
138
179
  ...(options.lane ? { lane: options.lane } : {}),
180
+ ...(options.modelDecisions ? { modelDecisions: options.modelDecisions } : {}),
181
+ ...(toolDefinitions ? { toolDefinitions: true } : {}),
139
182
  });
183
+ const heldBack = (m) => engine.getModelDecisions() === 'advisory' && isModelDecided(m);
140
184
  await engine.loadRules();
141
185
  if (semantic.enabled && !options.json && !options.sarif) {
142
186
  console.error(`${DIM}Semantic judge: enabled for method=semantic rules${RESET}`);
@@ -146,9 +190,14 @@ async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
146
190
  const allResults = [];
147
191
  let totalThreats = 0;
148
192
  let failHits = 0;
193
+ let eventsEvaluated = 0;
194
+ let eventsSkipped = 0;
149
195
  for (const event of events) {
150
- if (!event.content)
151
- continue; // skip malformed events
196
+ if (!event.content) {
197
+ eventsSkipped += 1; // skip malformed events, but never silently
198
+ continue;
199
+ }
200
+ eventsEvaluated += 1;
152
201
  const result = semantic.enabled
153
202
  ? await engine.evaluateFullAsync(event, eventsPath)
154
203
  : engine.evaluateFull(event, eventsPath);
@@ -157,48 +206,85 @@ async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
157
206
  allResults.push({ event, result, filtered });
158
207
  totalThreats += filtered.length;
159
208
  if (failIdx >= 0) {
160
- failHits += filtered.filter((m) => SEVERITY_ORDER.indexOf(m.rule.severity) >= failIdx).length;
209
+ failHits += filtered.filter((m) => !heldBack(m) && SEVERITY_ORDER.indexOf(m.rule.severity) >= failIdx).length;
161
210
  }
162
211
  }
163
212
  }
213
+ // An event that never reached the engine is not a clean result, and the counts have to say so:
214
+ // `events_scanned` used to be `events.length`, computed before the skip.
215
+ if (events.length === 0) {
216
+ console.error(`${RED}Error: nothing was scanned — the input contains no events and no tools${RESET}`);
217
+ }
218
+ else if (eventsEvaluated === 0) {
219
+ console.error(`${RED}Error: nothing was scanned — ${eventsSkipped} event(s) had no content${RESET}`);
220
+ }
221
+ else if (eventsSkipped > 0) {
222
+ console.error(`${DIM}Warning: ${eventsSkipped} event(s) had no content and were not scanned${RESET}`);
223
+ }
224
+ // On a tools/list document some rules do not run (src/tool-definition-scope.ts): say so, and how
225
+ // many, so "not run" cannot read as "ran and found nothing"; and name the tool of each result.
226
+ const scope = engine.getToolDefinitionScope();
227
+ const scopeReport = scope
228
+ ? { tool_definition_scope: true, rules_evaluated: scope.rulesEvaluated, rules_skipped_by_scope: scope.rulesSkippedByScope }
229
+ : {};
230
+ const toolNameOf = (event) => toolDefinitions ? event.fields?.['tool_name'] : undefined;
164
231
  if (options.sarif) {
165
- const sarifResults = allResults.map(({ result, filtered }) => ({
166
- ...result,
167
- matches: filtered,
168
- threat_count: filtered.length,
169
- }));
232
+ const toolNames = new Map();
233
+ const sarifResults = allResults.map(({ event, result, filtered }) => {
234
+ const scoped = { ...result, matches: filtered, threat_count: filtered.length };
235
+ const name = toolNameOf(event);
236
+ if (name !== undefined)
237
+ toolNames.set(scoped, name);
238
+ return scoped;
239
+ });
170
240
  const version = process.env['npm_package_version'] ?? '1.0.0';
171
- console.log(JSON.stringify(scanResultToSARIF(sarifResults, version), null, 2));
172
- return failHits;
241
+ console.log(JSON.stringify(scanResultToSARIF(sarifResults, version, {
242
+ heldBack,
243
+ ...(scope ? { runProperties: scopeReport } : {}),
244
+ resultProperties: (r) => (toolNames.has(r) ? { tool_name: toolNames.get(r) } : undefined),
245
+ }), null, 2));
246
+ return eventsEvaluated === 0 ? 1 : failHits;
173
247
  }
174
248
  if (options.json) {
175
249
  console.log(JSON.stringify({
176
250
  scan_type: 'mcp',
177
- events_scanned: events.length,
251
+ events_scanned: eventsEvaluated,
252
+ events_skipped: eventsSkipped,
178
253
  threats_detected: totalThreats,
179
254
  rules_loaded: engine.getRuleCount(),
180
- results: allResults.map(({ event, result, filtered }) => ({
181
- content_hash: result.content_hash,
182
- event: {
183
- type: event.type,
184
- timestamp: event.timestamp,
185
- content_preview: event.content.slice(0, 100),
186
- },
187
- matches: filtered.map(formatMatchJson),
188
- })),
255
+ ...scopeReport,
256
+ results: allResults.map(({ event, result, filtered }) => {
257
+ const toolName = toolNameOf(event);
258
+ return {
259
+ content_hash: result.content_hash,
260
+ event: {
261
+ type: event.type,
262
+ timestamp: event.timestamp,
263
+ ...(toolName !== undefined ? { tool_name: toolName } : {}),
264
+ content_preview: event.content.slice(0, 100),
265
+ },
266
+ matches: filtered.map((m) => formatMatchJson(m, heldBack(m))),
267
+ };
268
+ }),
189
269
  }, null, 2));
190
- return failHits;
270
+ return eventsEvaluated === 0 ? 1 : failHits;
271
+ }
272
+ printScanHeader('MCP', eventsEvaluated, engine.getRuleCount(), totalThreats);
273
+ if (scope) {
274
+ console.log(`${DIM} Tool definitions: ${scope.rulesSkippedByScope} rule(s) written for a tool being called were not run; ${scope.rulesEvaluated} were.${RESET}\n`);
191
275
  }
192
- printScanHeader('MCP', events.length, engine.getRuleCount(), totalThreats);
193
276
  if (totalThreats === 0) {
194
- console.log(`${GREEN}No threats detected.${RESET}\n`);
195
- return failHits;
277
+ console.log(eventsEvaluated === 0
278
+ ? `${RED}Nothing was scanned.${RESET}\n`
279
+ : `${GREEN}No threats detected.${RESET}\n`);
280
+ return eventsEvaluated === 0 ? 1 : failHits;
196
281
  }
197
282
  for (const { event, filtered } of allResults) {
198
283
  const preview = event.content.slice(0, 80).replace(/\n/g, ' ');
199
- console.log(` ${DIM}Event: [${event.type}] "${preview}..."${RESET}`);
284
+ const toolName = toolNameOf(event);
285
+ console.log(` ${DIM}Event: [${event.type}]${toolName !== undefined ? ` tool ${toolName}` : ''} "${preview}..."${RESET}`);
200
286
  for (const m of filtered) {
201
- printMatch(m);
287
+ printMatch(m, heldBack(m));
202
288
  }
203
289
  console.log('');
204
290
  }
@@ -217,7 +303,9 @@ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
217
303
  reporter,
218
304
  semanticJudge: semantic.judge,
219
305
  ...(options.lane ? { lane: options.lane } : {}),
306
+ ...(options.modelDecisions ? { modelDecisions: options.modelDecisions } : {}),
220
307
  });
308
+ const heldBack = (m) => engine.getModelDecisions() === 'advisory' && isModelDecided(m);
221
309
  await engine.loadRules();
222
310
  if (semantic.enabled && !options.json && !options.sarif) {
223
311
  console.error(`${DIM}Semantic judge: enabled for method=semantic rules${RESET}`);
@@ -242,7 +330,7 @@ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
242
330
  allResults.push({ file, result, filtered });
243
331
  totalThreats += filtered.length;
244
332
  if (failIdx >= 0) {
245
- failHits += filtered.filter((m) => SEVERITY_ORDER.indexOf(m.rule.severity) >= failIdx).length;
333
+ failHits += filtered.filter((m) => !heldBack(m) && SEVERITY_ORDER.indexOf(m.rule.severity) >= failIdx).length;
246
334
  }
247
335
  }
248
336
  }
@@ -253,7 +341,7 @@ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
253
341
  threat_count: filtered.length,
254
342
  }));
255
343
  const version = process.env['npm_package_version'] ?? '1.0.0';
256
- console.log(JSON.stringify(scanResultToSARIF(sarifResults, version), null, 2));
344
+ console.log(JSON.stringify(scanResultToSARIF(sarifResults, version, { heldBack }), null, 2));
257
345
  return failHits;
258
346
  }
259
347
  if (options.json) {
@@ -265,7 +353,7 @@ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
265
353
  results: allResults.map(({ file, result, filtered }) => ({
266
354
  file,
267
355
  content_hash: result.content_hash,
268
- matches: filtered.map(formatMatchJson),
356
+ matches: filtered.map((m) => formatMatchJson(m, heldBack(m))),
269
357
  })),
270
358
  }, null, 2));
271
359
  return failHits;
@@ -279,7 +367,7 @@ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
279
367
  const relPath = file.replace(process.cwd() + '/', '');
280
368
  console.log(` ${BOLD}${relPath}${RESET}`);
281
369
  for (const m of filtered) {
282
- printMatch(m);
370
+ printMatch(m, heldBack(m));
283
371
  }
284
372
  console.log('');
285
373
  }
@@ -318,13 +406,16 @@ function walkForSkills(dir, out) {
318
406
  }
319
407
  }
320
408
  }
321
- function formatMatchJson(m) {
409
+ function formatMatchJson(m, heldBack) {
322
410
  return {
323
411
  rule_id: m.rule.id,
324
412
  title: m.rule.title,
325
413
  severity: m.rule.severity,
326
414
  confidence: m.confidence,
327
415
  matched_conditions: m.matchedConditions,
416
+ decided_by: m.decidedBy ?? null,
417
+ // false: a model decided it and it does not count toward --fail-on.
418
+ enforced: !heldBack,
328
419
  };
329
420
  }
330
421
  function printScanHeader(type, scanned, rulesLoaded, threats) {
@@ -338,9 +429,10 @@ function printScanHeader(type, scanned, rulesLoaded, threats) {
338
429
  console.log(`${DIM} Open source (MIT). Star: https://github.com/Agent-Threat-Rule/agent-threat-rules${RESET}`);
339
430
  console.log('');
340
431
  }
341
- function printMatch(m) {
432
+ function printMatch(m, heldBack) {
342
433
  const color = SEVERITY_COLORS[m.rule.severity] ?? '';
343
- console.log(` ${color}${m.rule.severity.toUpperCase().padEnd(13)}${RESET} ${m.rule.id} - ${m.rule.title}`);
434
+ const note = heldBack ? ` ${DIM}(decided by ${m.decidedBy}: reported, not counted toward --fail-on)${RESET}` : '';
435
+ console.log(` ${color}${m.rule.severity.toUpperCase().padEnd(13)}${RESET} ${m.rule.id} - ${m.rule.title}${note}`);
344
436
  console.log(` ${DIM}Confidence: ${(m.confidence * 100).toFixed(0)}% | Conditions: ${m.matchedConditions.join(', ')}${RESET}`);
345
437
  }
346
438
  //# sourceMappingURL=scan-handler.js.map