agent-threat-rules 1.1.0 → 1.2.0

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 (151) hide show
  1. package/README.md +38 -15
  2. package/dist/cli.js +16 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/engine.d.ts +5 -0
  5. package/dist/engine.d.ts.map +1 -1
  6. package/dist/engine.js +25 -2
  7. package/dist/engine.js.map +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/quality/adapters/atr.d.ts +65 -0
  13. package/dist/quality/adapters/atr.d.ts.map +1 -0
  14. package/dist/quality/adapters/atr.js +154 -0
  15. package/dist/quality/adapters/atr.js.map +1 -0
  16. package/dist/quality/adapters/index.d.ts +10 -0
  17. package/dist/quality/adapters/index.d.ts.map +1 -0
  18. package/dist/quality/adapters/index.js +10 -0
  19. package/dist/quality/adapters/index.js.map +1 -0
  20. package/dist/quality/compute-confidence.d.ts +45 -0
  21. package/dist/quality/compute-confidence.d.ts.map +1 -0
  22. package/dist/quality/compute-confidence.js +133 -0
  23. package/dist/quality/compute-confidence.js.map +1 -0
  24. package/dist/quality/index.d.ts +36 -0
  25. package/dist/quality/index.d.ts.map +1 -0
  26. package/dist/quality/index.js +39 -0
  27. package/dist/quality/index.js.map +1 -0
  28. package/dist/quality/quality-gate.d.ts +68 -0
  29. package/dist/quality/quality-gate.d.ts.map +1 -0
  30. package/dist/quality/quality-gate.js +140 -0
  31. package/dist/quality/quality-gate.js.map +1 -0
  32. package/dist/quality/types.d.ts +129 -0
  33. package/dist/quality/types.d.ts.map +1 -0
  34. package/dist/quality/types.js +10 -0
  35. package/dist/quality/types.js.map +1 -0
  36. package/dist/quality/validate-maturity.d.ts +51 -0
  37. package/dist/quality/validate-maturity.d.ts.map +1 -0
  38. package/dist/quality/validate-maturity.js +134 -0
  39. package/dist/quality/validate-maturity.js.map +1 -0
  40. package/dist/types.d.ts +20 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +6 -2
  43. package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +6 -2
  44. package/rules/agent-manipulation/ATR-2026-00032-goal-hijacking.yaml +4 -0
  45. package/rules/agent-manipulation/ATR-2026-00074-cross-agent-privilege-escalation.yaml +4 -0
  46. package/rules/agent-manipulation/ATR-2026-00076-inter-agent-message-spoofing.yaml +4 -0
  47. package/rules/agent-manipulation/ATR-2026-00077-human-trust-exploitation.yaml +4 -0
  48. package/rules/agent-manipulation/ATR-2026-00108-consensus-sybil-attack.yaml +4 -0
  49. package/rules/agent-manipulation/ATR-2026-00116-a2a-message-validation.yaml +4 -0
  50. package/rules/agent-manipulation/ATR-2026-00117-agent-identity-spoofing.yaml +10 -6
  51. package/rules/agent-manipulation/ATR-2026-00118-approval-fatigue.yaml +16 -6
  52. package/rules/agent-manipulation/ATR-2026-00119-social-engineering-via-agent.yaml +16 -6
  53. package/rules/agent-manipulation/ATR-2026-00132-casual-authority-escalation.yaml +9 -0
  54. package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +9 -0
  55. package/rules/context-exfiltration/ATR-2026-00020-system-prompt-leak.yaml +6 -2
  56. package/rules/context-exfiltration/ATR-2026-00021-api-key-exposure.yaml +6 -2
  57. package/rules/context-exfiltration/ATR-2026-00075-agent-memory-manipulation.yaml +4 -0
  58. package/rules/context-exfiltration/ATR-2026-00102-disguised-analytics-exfiltration.yaml +9 -0
  59. package/rules/context-exfiltration/ATR-2026-00113-credential-theft.yaml +16 -6
  60. package/rules/context-exfiltration/ATR-2026-00114-oauth-token-abuse.yaml +16 -6
  61. package/rules/context-exfiltration/ATR-2026-00115-env-var-harvesting.yaml +16 -6
  62. package/rules/context-exfiltration/ATR-2026-00136-tool-response-data-piggyback.yaml +4 -0
  63. package/rules/context-exfiltration/ATR-2026-00141-example-format-key-leak.yaml +9 -0
  64. package/rules/context-exfiltration/ATR-2026-00142-piggyback-transition-words.yaml +9 -0
  65. package/rules/context-exfiltration/ATR-2026-00145-obfuscated-key-disclosure.yaml +9 -0
  66. package/rules/context-exfiltration/ATR-2026-00146-env-var-existence-probe.yaml +9 -0
  67. package/rules/context-exfiltration/ATR-2026-00150-credential-in-tool-response.yaml +11 -2
  68. package/rules/context-exfiltration/ATR-2026-00152-obfuscated-credential-leak.yaml +9 -0
  69. package/rules/data-poisoning/ATR-2026-00070-data-poisoning.yaml +4 -0
  70. package/rules/excessive-autonomy/ATR-2026-00050-runaway-agent-loop.yaml +4 -0
  71. package/rules/excessive-autonomy/ATR-2026-00051-resource-exhaustion.yaml +4 -0
  72. package/rules/excessive-autonomy/ATR-2026-00052-cascading-failure.yaml +4 -0
  73. package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +4 -0
  74. package/rules/excessive-autonomy/ATR-2026-00099-high-risk-tool-gate.yaml +4 -0
  75. package/rules/model-security/ATR-2026-00072-model-behavior-extraction.yaml +4 -0
  76. package/rules/model-security/ATR-2026-00073-malicious-finetuning-data.yaml +4 -0
  77. package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +4 -0
  78. package/rules/privilege-escalation/ATR-2026-00041-scope-creep.yaml +4 -0
  79. package/rules/privilege-escalation/ATR-2026-00107-delayed-execution-bypass.yaml +4 -0
  80. package/rules/privilege-escalation/ATR-2026-00110-eval-injection.yaml +17 -7
  81. package/rules/privilege-escalation/ATR-2026-00111-shell-escape.yaml +16 -6
  82. package/rules/privilege-escalation/ATR-2026-00112-dynamic-import-exploitation.yaml +16 -6
  83. package/rules/privilege-escalation/ATR-2026-00143-casual-privilege-escalation.yaml +9 -0
  84. package/rules/privilege-escalation/ATR-2026-00144-rationalized-safety-bypass.yaml +9 -0
  85. package/rules/prompt-injection/ATR-2026-00001-direct-prompt-injection.yaml +7 -3
  86. package/rules/prompt-injection/ATR-2026-00002-indirect-prompt-injection.yaml +6 -2
  87. package/rules/prompt-injection/ATR-2026-00003-jailbreak-attempt.yaml +6 -2
  88. package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +4 -0
  89. package/rules/prompt-injection/ATR-2026-00005-multi-turn-injection.yaml +4 -0
  90. package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +9 -0
  91. package/rules/prompt-injection/ATR-2026-00081-semantic-multi-turn.yaml +9 -0
  92. package/rules/prompt-injection/ATR-2026-00082-fingerprint-evasion.yaml +9 -0
  93. package/rules/prompt-injection/ATR-2026-00083-indirect-tool-injection.yaml +9 -0
  94. package/rules/prompt-injection/ATR-2026-00084-structured-data-injection.yaml +9 -0
  95. package/rules/prompt-injection/ATR-2026-00085-audit-evasion.yaml +9 -0
  96. package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +9 -0
  97. package/rules/prompt-injection/ATR-2026-00087-rule-probing.yaml +9 -0
  98. package/rules/prompt-injection/ATR-2026-00088-adaptive-countermeasure.yaml +9 -0
  99. package/rules/prompt-injection/ATR-2026-00089-polymorphic-skill.yaml +9 -0
  100. package/rules/prompt-injection/ATR-2026-00090-threat-intel-exfil.yaml +9 -0
  101. package/rules/prompt-injection/ATR-2026-00091-nested-payload.yaml +9 -0
  102. package/rules/prompt-injection/ATR-2026-00092-consensus-poisoning.yaml +9 -0
  103. package/rules/prompt-injection/ATR-2026-00093-gradual-escalation.yaml +9 -0
  104. package/rules/prompt-injection/ATR-2026-00094-audit-bypass.yaml +9 -0
  105. package/rules/prompt-injection/ATR-2026-00097-cjk-injection-patterns.yaml +4 -0
  106. package/rules/prompt-injection/ATR-2026-00104-persona-hijacking.yaml +4 -0
  107. package/rules/prompt-injection/ATR-2026-00130-indirect-authority-claim.yaml +10 -1
  108. package/rules/prompt-injection/ATR-2026-00131-fictional-academic-framing.yaml +9 -0
  109. package/rules/prompt-injection/ATR-2026-00133-paraphrase-injection.yaml +9 -0
  110. package/rules/prompt-injection/ATR-2026-00137-authority-claim-injection.yaml +9 -0
  111. package/rules/prompt-injection/ATR-2026-00138-fictional-framing-bypass.yaml +9 -0
  112. package/rules/prompt-injection/ATR-2026-00140-indirect-reference-reversal.yaml +9 -0
  113. package/rules/prompt-injection/ATR-2026-00148-language-switch-injection.yaml +9 -0
  114. package/rules/prompt-injection/ATR-2026-00153-tool-with-embedded-instruction-to-bypass.yaml +16 -0
  115. package/rules/prompt-injection/ATR-2026-00154-unauthorized-background-task-execution-v.yaml +16 -0
  116. package/rules/prompt-injection/ATR-2026-00155-hidden-llm-instructions-in-skill-descrip.yaml +16 -0
  117. package/rules/prompt-injection/ATR-2026-00156-ssh-remote-command-execution-with-creden.yaml +16 -0
  118. package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +4 -0
  119. package/rules/skill-compromise/ATR-2026-00061-description-behavior-mismatch.yaml +4 -0
  120. package/rules/skill-compromise/ATR-2026-00062-hidden-capability.yaml +4 -0
  121. package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +4 -0
  122. package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +4 -0
  123. package/rules/skill-compromise/ATR-2026-00065-skill-update-attack.yaml +4 -0
  124. package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +4 -0
  125. package/rules/skill-compromise/ATR-2026-00120-skill-instruction-injection.yaml +10 -1
  126. package/rules/skill-compromise/ATR-2026-00121-skill-dangerous-script.yaml +11 -2
  127. package/rules/skill-compromise/ATR-2026-00122-skill-weaponized-instruction.yaml +9 -0
  128. package/rules/skill-compromise/ATR-2026-00123-skill-overreach-permissions.yaml +10 -1
  129. package/rules/skill-compromise/ATR-2026-00124-skill-name-squatting.yaml +9 -0
  130. package/rules/skill-compromise/ATR-2026-00125-context-poisoning-compaction.yaml +9 -0
  131. package/rules/skill-compromise/ATR-2026-00126-skill-rug-pull-setup.yaml +9 -0
  132. package/rules/skill-compromise/ATR-2026-00127-subcommand-overflow.yaml +9 -0
  133. package/rules/skill-compromise/ATR-2026-00128-html-comment-hidden-payload.yaml +9 -0
  134. package/rules/skill-compromise/ATR-2026-00129-unicode-smuggling.yaml +9 -0
  135. package/rules/skill-compromise/ATR-2026-00134-fork-claim-impersonation.yaml +14 -0
  136. package/rules/skill-compromise/ATR-2026-00135-exfil-url-in-instructions.yaml +9 -0
  137. package/rules/skill-compromise/ATR-2026-00147-fork-impersonation.yaml +10 -1
  138. package/rules/skill-compromise/ATR-2026-00149-skill-exfil-compound.yaml +9 -0
  139. package/rules/skill-compromise/ATR-2026-00151-fork-impersonation-install.yaml +9 -0
  140. package/rules/skill-compromise/ATR-2026-00157-timebomb-credential-exfil.yaml +121 -0
  141. package/rules/tool-poisoning/ATR-2026-00010-mcp-malicious-response.yaml +6 -2
  142. package/rules/tool-poisoning/ATR-2026-00011-tool-output-injection.yaml +4 -0
  143. package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +4 -0
  144. package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +4 -0
  145. package/rules/tool-poisoning/ATR-2026-00095-supply-chain-poisoning.yaml +9 -0
  146. package/rules/tool-poisoning/ATR-2026-00096-registry-poisoning.yaml +9 -0
  147. package/rules/tool-poisoning/ATR-2026-00100-consent-bypass-instruction.yaml +9 -0
  148. package/rules/tool-poisoning/ATR-2026-00101-trust-escalation-override.yaml +9 -0
  149. package/rules/tool-poisoning/ATR-2026-00103-hidden-safety-bypass-instruction.yaml +4 -0
  150. package/rules/tool-poisoning/ATR-2026-00105-silent-action-concealment.yaml +9 -0
  151. package/rules/tool-poisoning/ATR-2026-00106-schema-description-contradiction.yaml +9 -0
package/dist/index.js CHANGED
@@ -54,4 +54,6 @@ export { ActionExecutor } from './action-executor.js';
54
54
  export { DefaultAdapter } from './adapters/default-adapter.js';
55
55
  export { StdioAdapter } from './adapters/stdio-adapter.js';
56
56
  export { HookHandler } from './hook-handler.js';
57
+ // Quality Standard — RFC-001 reference implementation
58
+ export * as quality from './quality/index.js';
57
59
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,mEAAmE;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,oEAAoE;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGhE,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtF,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,kDAAkD;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,kDAAkD;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAQ/D,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,mEAAmE;AACnE,qDAAqD;AACrD,qDAAqD;AACrD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,mEAAmE;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,oEAAoE;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGhE,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtF,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,kDAAkD;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,kDAAkD;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAQ/D,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,mEAAmE;AACnE,qDAAqD;AACrD,qDAAqD;AACrD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,sDAAsD;AACtD,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * ATR Quality Standard — ATR YAML Adapter
3
+ *
4
+ * Parses an ATR YAML rule (either as raw string or pre-parsed object) and
5
+ * produces RuleMetadata that the quality gate and scoring functions
6
+ * understand.
7
+ *
8
+ * @module agent-threat-rules/quality/adapters/atr
9
+ */
10
+ import type { RuleMetadata } from "../types.js";
11
+ /**
12
+ * Loose shape of an ATR rule file — matches what actually appears in
13
+ * rules/**\/*.yaml, not the strict type. This lets us adapt rules even if
14
+ * they're missing optional fields.
15
+ */
16
+ interface RawATRRule {
17
+ id?: string;
18
+ title?: string;
19
+ status?: string;
20
+ maturity?: string;
21
+ detection?: {
22
+ conditions?: unknown;
23
+ false_positives?: unknown[];
24
+ };
25
+ test_cases?: {
26
+ true_positives?: unknown[];
27
+ true_negatives?: unknown[];
28
+ };
29
+ evasion_tests?: unknown[];
30
+ references?: {
31
+ owasp_llm?: unknown[];
32
+ owasp_agentic?: unknown[];
33
+ mitre_atlas?: unknown[];
34
+ mitre_attack?: unknown[];
35
+ };
36
+ author?: string;
37
+ wild_samples?: number;
38
+ wild_fp_rate?: number;
39
+ wild_validated?: string;
40
+ metadata_provenance?: {
41
+ mitre_atlas?: string;
42
+ mitre_attack?: string;
43
+ owasp_llm?: string;
44
+ owasp_agentic?: string;
45
+ test_cases?: string;
46
+ evasion_tests?: string;
47
+ false_positives?: string;
48
+ };
49
+ }
50
+ /**
51
+ * Parse an ATR YAML rule string into RuleMetadata.
52
+ *
53
+ * @param yamlContent - Raw YAML content
54
+ * @returns RuleMetadata (throws if YAML is invalid or missing required fields)
55
+ */
56
+ export declare function parseATRRule(yamlContent: string): RuleMetadata;
57
+ /**
58
+ * Convert a parsed ATR rule object into RuleMetadata.
59
+ *
60
+ * Accepts the loose shape returned by yaml.load() so callers that already
61
+ * have a parsed object don't need to re-serialize.
62
+ */
63
+ export declare function atrRuleToMetadata(rule: RawATRRule): RuleMetadata;
64
+ export {};
65
+ //# sourceMappingURL=atr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atr.d.ts","sourceRoot":"","sources":["../../../src/quality/adapters/atr.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,UAAU,UAAU;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;KAC7B,CAAC;IACF,UAAU,CAAC,EAAE;QACX,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;QAC3B,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;KAC5B,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;QACtB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;QAC1B,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;KAC1B,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CA2DhE"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * ATR Quality Standard — ATR YAML Adapter
3
+ *
4
+ * Parses an ATR YAML rule (either as raw string or pre-parsed object) and
5
+ * produces RuleMetadata that the quality gate and scoring functions
6
+ * understand.
7
+ *
8
+ * @module agent-threat-rules/quality/adapters/atr
9
+ */
10
+ import { load as parseYaml } from "js-yaml";
11
+ /**
12
+ * Parse an ATR YAML rule string into RuleMetadata.
13
+ *
14
+ * @param yamlContent - Raw YAML content
15
+ * @returns RuleMetadata (throws if YAML is invalid or missing required fields)
16
+ */
17
+ export function parseATRRule(yamlContent) {
18
+ const parsed = parseYaml(yamlContent);
19
+ if (!parsed || typeof parsed !== "object") {
20
+ throw new Error("Invalid YAML: not an object");
21
+ }
22
+ return atrRuleToMetadata(parsed);
23
+ }
24
+ /**
25
+ * Convert a parsed ATR rule object into RuleMetadata.
26
+ *
27
+ * Accepts the loose shape returned by yaml.load() so callers that already
28
+ * have a parsed object don't need to re-serialize.
29
+ */
30
+ export function atrRuleToMetadata(rule) {
31
+ const id = rule.id ?? "<unknown>";
32
+ const title = rule.title ?? "<untitled>";
33
+ // Prefer `maturity` field; fall back to `status` if maturity is absent.
34
+ // Normalize common aliases: `test` -> `experimental`, anything unknown -> `draft`.
35
+ const rawMaturity = (rule.maturity ?? rule.status ?? "draft").toLowerCase();
36
+ const maturity = normalizeMaturity(rawMaturity);
37
+ const conditions = countConditions(rule.detection?.conditions);
38
+ const truePositives = Array.isArray(rule.test_cases?.true_positives)
39
+ ? rule.test_cases.true_positives.length
40
+ : 0;
41
+ const trueNegatives = Array.isArray(rule.test_cases?.true_negatives)
42
+ ? rule.test_cases.true_negatives.length
43
+ : 0;
44
+ const evasionTests = Array.isArray(rule.evasion_tests)
45
+ ? rule.evasion_tests.length
46
+ : 0;
47
+ const hasOwaspRef = hasAnyArrayItem(rule.references?.owasp_llm) ||
48
+ hasAnyArrayItem(rule.references?.owasp_agentic);
49
+ const hasMitreRef = hasAnyArrayItem(rule.references?.mitre_atlas) ||
50
+ hasAnyArrayItem(rule.references?.mitre_attack);
51
+ const hasFalsePositiveDocs = Array.isArray(rule.detection?.false_positives) &&
52
+ rule.detection.false_positives.length > 0;
53
+ // LLM-generated detection: author contains "Crystallization" or "LLM"
54
+ const author = (rule.author ?? "").toLowerCase();
55
+ const llmGenerated = author.includes("crystallization") ||
56
+ author.includes("llm") ||
57
+ author.includes("mirofish");
58
+ const provenance = extractProvenance(rule.metadata_provenance);
59
+ return {
60
+ id,
61
+ title,
62
+ maturity,
63
+ conditions,
64
+ truePositives,
65
+ trueNegatives,
66
+ evasionTests,
67
+ hasOwaspRef,
68
+ hasMitreRef,
69
+ hasFalsePositiveDocs,
70
+ ...(rule.wild_samples !== undefined
71
+ ? { wildSamples: rule.wild_samples }
72
+ : {}),
73
+ ...(rule.wild_fp_rate !== undefined
74
+ ? { wildFpRate: rule.wild_fp_rate }
75
+ : {}),
76
+ ...(rule.wild_validated ? { wildValidatedAt: rule.wild_validated } : {}),
77
+ ...(llmGenerated ? { llmGenerated: true } : {}),
78
+ ...(provenance ? { provenance } : {}),
79
+ };
80
+ }
81
+ /** Parse metadata_provenance field and normalize values to Provenance enum */
82
+ function extractProvenance(raw) {
83
+ if (!raw || typeof raw !== "object")
84
+ return undefined;
85
+ const result = {
86
+ ...(raw.mitre_atlas
87
+ ? { mitre_atlas: normalizeProvenance(raw.mitre_atlas) }
88
+ : {}),
89
+ ...(raw.mitre_attack
90
+ ? { mitre_attack: normalizeProvenance(raw.mitre_attack) }
91
+ : {}),
92
+ ...(raw.owasp_llm ? { owasp_llm: normalizeProvenance(raw.owasp_llm) } : {}),
93
+ ...(raw.owasp_agentic
94
+ ? { owasp_agentic: normalizeProvenance(raw.owasp_agentic) }
95
+ : {}),
96
+ ...(raw.test_cases
97
+ ? { test_cases: normalizeProvenance(raw.test_cases) }
98
+ : {}),
99
+ ...(raw.evasion_tests
100
+ ? { evasion_tests: normalizeProvenance(raw.evasion_tests) }
101
+ : {}),
102
+ ...(raw.false_positives
103
+ ? { false_positives: normalizeProvenance(raw.false_positives) }
104
+ : {}),
105
+ };
106
+ return Object.keys(result).length > 0 ? result : undefined;
107
+ }
108
+ function normalizeProvenance(raw) {
109
+ const v = raw.toLowerCase().trim();
110
+ if (v === "human-reviewed" || v === "human")
111
+ return "human-reviewed";
112
+ if (v === "community-contributed" || v === "community")
113
+ return "community-contributed";
114
+ if (v === "auto-generated" || v === "auto")
115
+ return "auto-generated";
116
+ if (v === "llm-generated" || v === "llm")
117
+ return "llm-generated";
118
+ // Unknown value — treat as auto-generated (conservative)
119
+ return "auto-generated";
120
+ }
121
+ /**
122
+ * ATR rules use two different condition formats:
123
+ * - Array: `conditions: [{ field, operator, value }, ...]`
124
+ * - Named map: `conditions: { name1: {...}, name2: {...} }`
125
+ *
126
+ * Count layers in either format.
127
+ */
128
+ function countConditions(conditions) {
129
+ if (Array.isArray(conditions))
130
+ return conditions.length;
131
+ if (conditions !== null && typeof conditions === "object") {
132
+ return Object.keys(conditions).length;
133
+ }
134
+ return 0;
135
+ }
136
+ function hasAnyArrayItem(value) {
137
+ return Array.isArray(value) && value.length > 0;
138
+ }
139
+ function normalizeMaturity(raw) {
140
+ switch (raw) {
141
+ case "draft":
142
+ return "draft";
143
+ case "experimental":
144
+ case "test": // ATR legacy alias
145
+ return "experimental";
146
+ case "stable":
147
+ return "stable";
148
+ case "deprecated":
149
+ return "deprecated";
150
+ default:
151
+ return "draft";
152
+ }
153
+ }
154
+ //# sourceMappingURL=atr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atr.js","sourceRoot":"","sources":["../../../src/quality/adapters/atr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * ATR Quality Standard — Rule Format Adapters
3
+ *
4
+ * Adapters convert vendor-specific rule formats into the canonical
5
+ * RuleMetadata interface that the scoring and validation functions consume.
6
+ *
7
+ * @module agent-threat-rules/quality/adapters
8
+ */
9
+ export { parseATRRule, atrRuleToMetadata } from "./atr.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/quality/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * ATR Quality Standard — Rule Format Adapters
3
+ *
4
+ * Adapters convert vendor-specific rule formats into the canonical
5
+ * RuleMetadata interface that the scoring and validation functions consume.
6
+ *
7
+ * @module agent-threat-rules/quality/adapters
8
+ */
9
+ export { parseATRRule, atrRuleToMetadata } from "./atr.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/quality/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ATR Quality Standard — Confidence Scoring
3
+ *
4
+ * Pure function implementing the RFC-001 §2 confidence formula:
5
+ *
6
+ * confidence = round(
7
+ * precision_score * 0.40
8
+ * + wild_validation * 0.30
9
+ * + coverage_score * 0.20
10
+ * + evasion_docs * 0.10
11
+ * )
12
+ *
13
+ * @module agent-threat-rules/quality/compute-confidence
14
+ */
15
+ import type { ConfidenceScore, DeploymentRecommendation, RuleMetadata } from "./types.js";
16
+ /**
17
+ * Compute the confidence score for a rule.
18
+ *
19
+ * Score is in [0, 100]. Higher is more trustworthy.
20
+ *
21
+ * @param rule - Rule metadata (vendor-agnostic)
22
+ * @returns Score breakdown and total
23
+ */
24
+ export declare function computeConfidence(rule: RuleMetadata): ConfidenceScore;
25
+ /**
26
+ * Map a confidence score to a deployment recommendation.
27
+ *
28
+ * This is the consumer-facing signal: "should I deploy this rule in
29
+ * blocking mode, alert mode, or not at all?"
30
+ */
31
+ export declare function deploymentFor(score: number): DeploymentRecommendation;
32
+ /**
33
+ * Apply the cross-context penalty to a match's contribution.
34
+ *
35
+ * When a rule designed for one scan context (e.g. MCP runtime) fires in
36
+ * a different context (e.g. SKILL.md static scan), the match's contribution
37
+ * is downweighted by 0.7. This prevents cross-context noise from inflating
38
+ * overall detection confidence.
39
+ *
40
+ * @param score - The base confidence score of the rule
41
+ * @param isCrossContext - True if the match is outside the rule's native context
42
+ * @returns Adjusted score
43
+ */
44
+ export declare function applyCrossContextPenalty(score: number, isCrossContext: boolean): number;
45
+ //# sourceMappingURL=compute-confidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-confidence.d.ts","sourceRoot":"","sources":["../../src/quality/compute-confidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,YAAY,EACb,MAAM,YAAY,CAAC;AAKpB;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,CAiCrE;AAuDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAMrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,OAAO,GACtB,MAAM,CAER"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * ATR Quality Standard — Confidence Scoring
3
+ *
4
+ * Pure function implementing the RFC-001 §2 confidence formula:
5
+ *
6
+ * confidence = round(
7
+ * precision_score * 0.40
8
+ * + wild_validation * 0.30
9
+ * + coverage_score * 0.20
10
+ * + evasion_docs * 0.10
11
+ * )
12
+ *
13
+ * @module agent-threat-rules/quality/compute-confidence
14
+ */
15
+ /** Max confidence an LLM-generated rule can reach without human review */
16
+ const LLM_CAP_WITHOUT_REVIEW = 70;
17
+ /**
18
+ * Compute the confidence score for a rule.
19
+ *
20
+ * Score is in [0, 100]. Higher is more trustworthy.
21
+ *
22
+ * @param rule - Rule metadata (vendor-agnostic)
23
+ * @returns Score breakdown and total
24
+ */
25
+ export function computeConfidence(rule) {
26
+ const precisionScore = computePrecisionScore(rule);
27
+ const wildValidationScore = computeWildValidationScore(rule);
28
+ const coverageScore = computeCoverageScore(rule);
29
+ const evasionScore = computeEvasionScore(rule);
30
+ const rawTotal = precisionScore * 0.4 +
31
+ wildValidationScore * 0.3 +
32
+ coverageScore * 0.2 +
33
+ evasionScore * 0.1;
34
+ let total = Math.round(rawTotal);
35
+ let capped = false;
36
+ // LLM-generated rules are capped at LLM_CAP_WITHOUT_REVIEW until a human reviews them.
37
+ // Rationale: LLMs can produce subtly wrong rules that pass static validation
38
+ // but fail in the wild. Human review is the only reliable backstop.
39
+ if (rule.llmGenerated === true && rule.humanReviewed !== true) {
40
+ if (total > LLM_CAP_WITHOUT_REVIEW) {
41
+ total = LLM_CAP_WITHOUT_REVIEW;
42
+ capped = true;
43
+ }
44
+ }
45
+ return {
46
+ total,
47
+ precisionScore: Math.round(precisionScore),
48
+ wildValidationScore: Math.round(wildValidationScore),
49
+ coverageScore: Math.round(coverageScore),
50
+ evasionScore: Math.round(evasionScore),
51
+ capped,
52
+ };
53
+ }
54
+ /**
55
+ * Precision component (weight 0.40).
56
+ *
57
+ * If wild FP rate is measured, use it directly: (1 - fpRate/100) * 100.
58
+ * Otherwise, estimate from test case coverage: more test cases = higher
59
+ * confidence in precision (max at 10 total).
60
+ */
61
+ function computePrecisionScore(rule) {
62
+ if (rule.wildFpRate !== undefined &&
63
+ rule.wildSamples !== undefined &&
64
+ rule.wildSamples > 0) {
65
+ const fpRate = Math.max(0, Math.min(100, rule.wildFpRate));
66
+ return 100 - fpRate;
67
+ }
68
+ // Fallback: estimate from test case depth
69
+ const testCaseCount = rule.truePositives + rule.trueNegatives;
70
+ return Math.min(testCaseCount / 10, 1) * 100;
71
+ }
72
+ /**
73
+ * Wild validation component (weight 0.30).
74
+ *
75
+ * Scales with sample size up to 10,000 samples. More real-world data
76
+ * = higher score. A rule tested on 0 samples gets 0. A rule tested on
77
+ * 10,000+ samples gets 100.
78
+ */
79
+ function computeWildValidationScore(rule) {
80
+ const samples = rule.wildSamples ?? 0;
81
+ return Math.min(samples / 10000, 1) * 100;
82
+ }
83
+ /**
84
+ * Coverage component (weight 0.20).
85
+ *
86
+ * Scales with number of detection conditions (layers). A single-condition
87
+ * rule gets 20. A 5+ condition rule gets 100. Defense in depth matters.
88
+ */
89
+ function computeCoverageScore(rule) {
90
+ return Math.min(rule.conditions / 5, 1) * 100;
91
+ }
92
+ /**
93
+ * Evasion documentation component (weight 0.10).
94
+ *
95
+ * Rewards honest acknowledgment of known bypasses. A rule with 0 evasion
96
+ * tests gets 0. A rule with 5+ evasion tests gets 100.
97
+ */
98
+ function computeEvasionScore(rule) {
99
+ return Math.min(rule.evasionTests / 5, 1) * 100;
100
+ }
101
+ /**
102
+ * Map a confidence score to a deployment recommendation.
103
+ *
104
+ * This is the consumer-facing signal: "should I deploy this rule in
105
+ * blocking mode, alert mode, or not at all?"
106
+ */
107
+ export function deploymentFor(score) {
108
+ if (score >= 90)
109
+ return "block-in-production";
110
+ if (score >= 80)
111
+ return "block-with-monitoring";
112
+ if (score >= 60)
113
+ return "alert-only";
114
+ if (score >= 40)
115
+ return "evaluation-only";
116
+ return "do-not-deploy";
117
+ }
118
+ /**
119
+ * Apply the cross-context penalty to a match's contribution.
120
+ *
121
+ * When a rule designed for one scan context (e.g. MCP runtime) fires in
122
+ * a different context (e.g. SKILL.md static scan), the match's contribution
123
+ * is downweighted by 0.7. This prevents cross-context noise from inflating
124
+ * overall detection confidence.
125
+ *
126
+ * @param score - The base confidence score of the rule
127
+ * @param isCrossContext - True if the match is outside the rule's native context
128
+ * @returns Adjusted score
129
+ */
130
+ export function applyCrossContextPenalty(score, isCrossContext) {
131
+ return isCrossContext ? Math.round(score * 0.7) : score;
132
+ }
133
+ //# sourceMappingURL=compute-confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-confidence.js","sourceRoot":"","sources":["../../src/quality/compute-confidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * ATR Quality Standard — Public API
3
+ *
4
+ * Vendor-neutral library for scoring and validating AI agent threat detection
5
+ * rules. See docs/proposals/001-atr-quality-standard-rfc.md for the RFC.
6
+ *
7
+ * @example Compute a confidence score for an ATR rule
8
+ * ```typescript
9
+ * import { parseATRRule, computeConfidence } from 'agent-threat-rules/quality';
10
+ * import { readFileSync } from 'node:fs';
11
+ *
12
+ * const yaml = readFileSync('rules/prompt-injection/ATR-2026-00001.yaml', 'utf-8');
13
+ * const rule = parseATRRule(yaml);
14
+ * const score = computeConfidence(rule);
15
+ * console.log(`Confidence: ${score.total}/100`);
16
+ * ```
17
+ *
18
+ * @example Run a rule through the quality gate
19
+ * ```typescript
20
+ * import { parseATRRule, validateRuleMeetsStandard } from 'agent-threat-rules/quality';
21
+ *
22
+ * const rule = parseATRRule(yamlContent);
23
+ * const gate = validateRuleMeetsStandard(rule, 'experimental');
24
+ * if (!gate.passed) {
25
+ * console.error('Rule rejected:', gate.issues);
26
+ * }
27
+ * ```
28
+ *
29
+ * @module agent-threat-rules/quality
30
+ */
31
+ export type { Maturity, RuleMetadata, ConfidenceScore, QualityGateResult, PromotionDecision, DemotionDecision, FpReport, DeploymentRecommendation, } from "./types.js";
32
+ export { computeConfidence, deploymentFor, applyCrossContextPenalty, } from "./compute-confidence.js";
33
+ export { validateRuleMeetsStandard, getRequirements } from "./quality-gate.js";
34
+ export { canPromote, shouldDemote, getMaturityThresholds, } from "./validate-maturity.js";
35
+ export { parseATRRule, atrRuleToMetadata } from "./adapters/atr.js";
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/quality/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EACL,UAAU,EACV,YAAY,EACZ,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * ATR Quality Standard — Public API
3
+ *
4
+ * Vendor-neutral library for scoring and validating AI agent threat detection
5
+ * rules. See docs/proposals/001-atr-quality-standard-rfc.md for the RFC.
6
+ *
7
+ * @example Compute a confidence score for an ATR rule
8
+ * ```typescript
9
+ * import { parseATRRule, computeConfidence } from 'agent-threat-rules/quality';
10
+ * import { readFileSync } from 'node:fs';
11
+ *
12
+ * const yaml = readFileSync('rules/prompt-injection/ATR-2026-00001.yaml', 'utf-8');
13
+ * const rule = parseATRRule(yaml);
14
+ * const score = computeConfidence(rule);
15
+ * console.log(`Confidence: ${score.total}/100`);
16
+ * ```
17
+ *
18
+ * @example Run a rule through the quality gate
19
+ * ```typescript
20
+ * import { parseATRRule, validateRuleMeetsStandard } from 'agent-threat-rules/quality';
21
+ *
22
+ * const rule = parseATRRule(yamlContent);
23
+ * const gate = validateRuleMeetsStandard(rule, 'experimental');
24
+ * if (!gate.passed) {
25
+ * console.error('Rule rejected:', gate.issues);
26
+ * }
27
+ * ```
28
+ *
29
+ * @module agent-threat-rules/quality
30
+ */
31
+ // Scoring
32
+ export { computeConfidence, deploymentFor, applyCrossContextPenalty, } from "./compute-confidence.js";
33
+ // Validation
34
+ export { validateRuleMeetsStandard, getRequirements } from "./quality-gate.js";
35
+ // Maturity transitions
36
+ export { canPromote, shouldDemote, getMaturityThresholds, } from "./validate-maturity.js";
37
+ // Adapters
38
+ export { parseATRRule, atrRuleToMetadata } from "./adapters/atr.js";
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/quality/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAcH,UAAU;AACV,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAEjC,aAAa;AACb,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE/E,uBAAuB;AACvB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,WAAW;AACX,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * ATR Quality Standard — Quality Gate
3
+ *
4
+ * Checks whether a rule meets the minimum quality bar for a target maturity
5
+ * level. Used by TC crystallization pipeline to reject weak LLM-generated
6
+ * rules before they enter the proposal pipeline.
7
+ *
8
+ * See docs/proposals/001-atr-quality-standard-rfc.md §3 for the required
9
+ * metadata matrix.
10
+ *
11
+ * @module agent-threat-rules/quality/quality-gate
12
+ */
13
+ import type { Maturity, QualityGateResult, RuleMetadata } from "./types.js";
14
+ /**
15
+ * Minimum requirements for each maturity level.
16
+ * Thresholds match RFC-001 §3. Adjust here to tune the bar.
17
+ *
18
+ * The experimental gate uses 3/3 (matching Cisco-merge practice) and
19
+ * accepts any provenance (auto-generated OK). The stable gate requires
20
+ * 5/5 with 3 evasion tests AND human-reviewed provenance for MITRE/OWASP.
21
+ */
22
+ declare const REQUIREMENTS: {
23
+ readonly draft: {
24
+ readonly minConditions: 1;
25
+ readonly minTruePositives: 1;
26
+ readonly minTrueNegatives: 1;
27
+ readonly minEvasionTests: 0;
28
+ readonly requireOwasp: false;
29
+ readonly requireMitre: false;
30
+ readonly requireFalsePositiveDocs: false;
31
+ readonly requireHumanReviewedProvenance: false;
32
+ };
33
+ readonly experimental: {
34
+ readonly minConditions: 3;
35
+ readonly minTruePositives: 3;
36
+ readonly minTrueNegatives: 3;
37
+ readonly minEvasionTests: 0;
38
+ readonly requireOwasp: true;
39
+ readonly requireMitre: true;
40
+ readonly requireFalsePositiveDocs: true;
41
+ readonly requireHumanReviewedProvenance: false;
42
+ };
43
+ readonly stable: {
44
+ readonly minConditions: 3;
45
+ readonly minTruePositives: 5;
46
+ readonly minTrueNegatives: 5;
47
+ readonly minEvasionTests: 3;
48
+ readonly requireOwasp: true;
49
+ readonly requireMitre: true;
50
+ readonly requireFalsePositiveDocs: true;
51
+ readonly requireHumanReviewedProvenance: true;
52
+ };
53
+ };
54
+ /**
55
+ * Validate a rule against the quality bar for a target maturity level.
56
+ *
57
+ * @param rule - Rule metadata
58
+ * @param target - Target maturity level to validate against (default: rule.maturity)
59
+ * @returns Gate result with passed/failed and human-readable issues
60
+ */
61
+ export declare function validateRuleMeetsStandard(rule: RuleMetadata, target?: Maturity): QualityGateResult;
62
+ /**
63
+ * Public accessor for the requirements table.
64
+ * Useful for documentation generators and UIs that display the quality bar.
65
+ */
66
+ export declare function getRequirements(): typeof REQUIREMENTS;
67
+ export {};
68
+ //# sourceMappingURL=quality-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-gate.d.ts","sourceRoot":"","sources":["../../src/quality/quality-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BR,CAAC;AAQX;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,QAAQ,GAChB,iBAAiB,CAiFnB;AAMD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,YAAY,CAErD"}