agent-threat-rules 1.1.1 → 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.
- package/README.md +38 -15
- package/dist/cli.js +16 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/quality/adapters/atr.d.ts +65 -0
- package/dist/quality/adapters/atr.d.ts.map +1 -0
- package/dist/quality/adapters/atr.js +154 -0
- package/dist/quality/adapters/atr.js.map +1 -0
- package/dist/quality/adapters/index.d.ts +10 -0
- package/dist/quality/adapters/index.d.ts.map +1 -0
- package/dist/quality/adapters/index.js +10 -0
- package/dist/quality/adapters/index.js.map +1 -0
- package/dist/quality/compute-confidence.d.ts +45 -0
- package/dist/quality/compute-confidence.d.ts.map +1 -0
- package/dist/quality/compute-confidence.js +133 -0
- package/dist/quality/compute-confidence.js.map +1 -0
- package/dist/quality/index.d.ts +36 -0
- package/dist/quality/index.d.ts.map +1 -0
- package/dist/quality/index.js +39 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/quality/quality-gate.d.ts +68 -0
- package/dist/quality/quality-gate.d.ts.map +1 -0
- package/dist/quality/quality-gate.js +140 -0
- package/dist/quality/quality-gate.js.map +1 -0
- package/dist/quality/types.d.ts +129 -0
- package/dist/quality/types.d.ts.map +1 -0
- package/dist/quality/types.js +10 -0
- package/dist/quality/types.js.map +1 -0
- package/dist/quality/validate-maturity.d.ts +51 -0
- package/dist/quality/validate-maturity.d.ts.map +1 -0
- package/dist/quality/validate-maturity.js +134 -0
- package/dist/quality/validate-maturity.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +6 -2
- package/rules/agent-manipulation/ATR-2026-00032-goal-hijacking.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00074-cross-agent-privilege-escalation.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00076-inter-agent-message-spoofing.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00077-human-trust-exploitation.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00108-consensus-sybil-attack.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00116-a2a-message-validation.yaml +4 -0
- package/rules/agent-manipulation/ATR-2026-00117-agent-identity-spoofing.yaml +10 -6
- package/rules/agent-manipulation/ATR-2026-00118-approval-fatigue.yaml +16 -6
- package/rules/agent-manipulation/ATR-2026-00119-social-engineering-via-agent.yaml +16 -6
- package/rules/agent-manipulation/ATR-2026-00132-casual-authority-escalation.yaml +9 -0
- package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00020-system-prompt-leak.yaml +6 -2
- package/rules/context-exfiltration/ATR-2026-00021-api-key-exposure.yaml +6 -2
- package/rules/context-exfiltration/ATR-2026-00075-agent-memory-manipulation.yaml +4 -0
- package/rules/context-exfiltration/ATR-2026-00102-disguised-analytics-exfiltration.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00113-credential-theft.yaml +16 -6
- package/rules/context-exfiltration/ATR-2026-00114-oauth-token-abuse.yaml +16 -6
- package/rules/context-exfiltration/ATR-2026-00115-env-var-harvesting.yaml +16 -6
- package/rules/context-exfiltration/ATR-2026-00136-tool-response-data-piggyback.yaml +4 -0
- package/rules/context-exfiltration/ATR-2026-00141-example-format-key-leak.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00142-piggyback-transition-words.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00145-obfuscated-key-disclosure.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00146-env-var-existence-probe.yaml +9 -0
- package/rules/context-exfiltration/ATR-2026-00150-credential-in-tool-response.yaml +11 -2
- package/rules/context-exfiltration/ATR-2026-00152-obfuscated-credential-leak.yaml +9 -0
- package/rules/data-poisoning/ATR-2026-00070-data-poisoning.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00050-runaway-agent-loop.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00051-resource-exhaustion.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00052-cascading-failure.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00099-high-risk-tool-gate.yaml +4 -0
- package/rules/model-security/ATR-2026-00072-model-behavior-extraction.yaml +4 -0
- package/rules/model-security/ATR-2026-00073-malicious-finetuning-data.yaml +4 -0
- package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +4 -0
- package/rules/privilege-escalation/ATR-2026-00041-scope-creep.yaml +4 -0
- package/rules/privilege-escalation/ATR-2026-00107-delayed-execution-bypass.yaml +4 -0
- package/rules/privilege-escalation/ATR-2026-00110-eval-injection.yaml +17 -7
- package/rules/privilege-escalation/ATR-2026-00111-shell-escape.yaml +16 -6
- package/rules/privilege-escalation/ATR-2026-00112-dynamic-import-exploitation.yaml +16 -6
- package/rules/privilege-escalation/ATR-2026-00143-casual-privilege-escalation.yaml +9 -0
- package/rules/privilege-escalation/ATR-2026-00144-rationalized-safety-bypass.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00001-direct-prompt-injection.yaml +7 -3
- package/rules/prompt-injection/ATR-2026-00002-indirect-prompt-injection.yaml +6 -2
- package/rules/prompt-injection/ATR-2026-00003-jailbreak-attempt.yaml +6 -2
- package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00005-multi-turn-injection.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00081-semantic-multi-turn.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00082-fingerprint-evasion.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00083-indirect-tool-injection.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00084-structured-data-injection.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00085-audit-evasion.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00087-rule-probing.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00088-adaptive-countermeasure.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00089-polymorphic-skill.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00090-threat-intel-exfil.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00091-nested-payload.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00092-consensus-poisoning.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00093-gradual-escalation.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00094-audit-bypass.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00097-cjk-injection-patterns.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00104-persona-hijacking.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00130-indirect-authority-claim.yaml +10 -1
- package/rules/prompt-injection/ATR-2026-00131-fictional-academic-framing.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00133-paraphrase-injection.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00137-authority-claim-injection.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00138-fictional-framing-bypass.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00140-indirect-reference-reversal.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00148-language-switch-injection.yaml +9 -0
- package/rules/prompt-injection/ATR-2026-00153-tool-with-embedded-instruction-to-bypass.yaml +16 -0
- package/rules/prompt-injection/ATR-2026-00154-unauthorized-background-task-execution-v.yaml +16 -0
- package/rules/prompt-injection/ATR-2026-00155-hidden-llm-instructions-in-skill-descrip.yaml +16 -0
- package/rules/prompt-injection/ATR-2026-00156-ssh-remote-command-execution-with-creden.yaml +16 -0
- package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00061-description-behavior-mismatch.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00062-hidden-capability.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00065-skill-update-attack.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +4 -0
- package/rules/skill-compromise/ATR-2026-00120-skill-instruction-injection.yaml +10 -1
- package/rules/skill-compromise/ATR-2026-00121-skill-dangerous-script.yaml +11 -2
- package/rules/skill-compromise/ATR-2026-00122-skill-weaponized-instruction.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00123-skill-overreach-permissions.yaml +10 -1
- package/rules/skill-compromise/ATR-2026-00124-skill-name-squatting.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00125-context-poisoning-compaction.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00126-skill-rug-pull-setup.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00127-subcommand-overflow.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00128-html-comment-hidden-payload.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00129-unicode-smuggling.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00134-fork-claim-impersonation.yaml +14 -0
- package/rules/skill-compromise/ATR-2026-00135-exfil-url-in-instructions.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00147-fork-impersonation.yaml +10 -1
- package/rules/skill-compromise/ATR-2026-00149-skill-exfil-compound.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00151-fork-impersonation-install.yaml +9 -0
- package/rules/skill-compromise/ATR-2026-00157-timebomb-credential-exfil.yaml +121 -0
- package/rules/tool-poisoning/ATR-2026-00010-mcp-malicious-response.yaml +6 -2
- package/rules/tool-poisoning/ATR-2026-00011-tool-output-injection.yaml +4 -0
- package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +4 -0
- package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +4 -0
- package/rules/tool-poisoning/ATR-2026-00095-supply-chain-poisoning.yaml +9 -0
- package/rules/tool-poisoning/ATR-2026-00096-registry-poisoning.yaml +9 -0
- package/rules/tool-poisoning/ATR-2026-00100-consent-bypass-instruction.yaml +9 -0
- package/rules/tool-poisoning/ATR-2026-00101-trust-escalation-override.yaml +9 -0
- package/rules/tool-poisoning/ATR-2026-00103-hidden-safety-bypass-instruction.yaml +4 -0
- package/rules/tool-poisoning/ATR-2026-00105-silent-action-concealment.yaml +9 -0
- package/rules/tool-poisoning/ATR-2026-00106-schema-description-contradiction.yaml +9 -0
|
@@ -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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
/**
|
|
14
|
+
* Minimum requirements for each maturity level.
|
|
15
|
+
* Thresholds match RFC-001 §3. Adjust here to tune the bar.
|
|
16
|
+
*
|
|
17
|
+
* The experimental gate uses 3/3 (matching Cisco-merge practice) and
|
|
18
|
+
* accepts any provenance (auto-generated OK). The stable gate requires
|
|
19
|
+
* 5/5 with 3 evasion tests AND human-reviewed provenance for MITRE/OWASP.
|
|
20
|
+
*/
|
|
21
|
+
const REQUIREMENTS = {
|
|
22
|
+
draft: {
|
|
23
|
+
minConditions: 1,
|
|
24
|
+
minTruePositives: 1,
|
|
25
|
+
minTrueNegatives: 1,
|
|
26
|
+
minEvasionTests: 0,
|
|
27
|
+
requireOwasp: false,
|
|
28
|
+
requireMitre: false,
|
|
29
|
+
requireFalsePositiveDocs: false,
|
|
30
|
+
requireHumanReviewedProvenance: false,
|
|
31
|
+
},
|
|
32
|
+
experimental: {
|
|
33
|
+
minConditions: 3,
|
|
34
|
+
minTruePositives: 3, // 3/3 matches Cisco-merge practice
|
|
35
|
+
minTrueNegatives: 3,
|
|
36
|
+
minEvasionTests: 0, // warning, not blocker
|
|
37
|
+
requireOwasp: true,
|
|
38
|
+
requireMitre: true,
|
|
39
|
+
requireFalsePositiveDocs: true,
|
|
40
|
+
requireHumanReviewedProvenance: false, // auto-generated OK for experimental
|
|
41
|
+
},
|
|
42
|
+
stable: {
|
|
43
|
+
minConditions: 3,
|
|
44
|
+
minTruePositives: 5,
|
|
45
|
+
minTrueNegatives: 5,
|
|
46
|
+
minEvasionTests: 3, // hard requirement
|
|
47
|
+
requireOwasp: true,
|
|
48
|
+
requireMitre: true,
|
|
49
|
+
requireFalsePositiveDocs: true,
|
|
50
|
+
requireHumanReviewedProvenance: true, // stable demands verified provenance
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
/** Provenance values that count as "verified" for stable promotion */
|
|
54
|
+
const VERIFIED_PROVENANCE = [
|
|
55
|
+
"human-reviewed",
|
|
56
|
+
"community-contributed",
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* Validate a rule against the quality bar for a target maturity level.
|
|
60
|
+
*
|
|
61
|
+
* @param rule - Rule metadata
|
|
62
|
+
* @param target - Target maturity level to validate against (default: rule.maturity)
|
|
63
|
+
* @returns Gate result with passed/failed and human-readable issues
|
|
64
|
+
*/
|
|
65
|
+
export function validateRuleMeetsStandard(rule, target) {
|
|
66
|
+
const level = target ?? rule.maturity;
|
|
67
|
+
// Deprecated rules are always valid (they're being retired, not used)
|
|
68
|
+
if (level === "deprecated") {
|
|
69
|
+
return { passed: true, issues: [], warnings: [] };
|
|
70
|
+
}
|
|
71
|
+
const req = REQUIREMENTS[level];
|
|
72
|
+
const issues = [];
|
|
73
|
+
const warnings = [];
|
|
74
|
+
if (rule.conditions < req.minConditions) {
|
|
75
|
+
issues.push(`only ${rule.conditions} detection condition(s) (need ${req.minConditions}+)`);
|
|
76
|
+
}
|
|
77
|
+
if (rule.truePositives < req.minTruePositives) {
|
|
78
|
+
issues.push(`only ${rule.truePositives} true_positive(s) (need ${req.minTruePositives}+)`);
|
|
79
|
+
}
|
|
80
|
+
if (rule.trueNegatives < req.minTrueNegatives) {
|
|
81
|
+
issues.push(`only ${rule.trueNegatives} true_negative(s) (need ${req.minTrueNegatives}+)`);
|
|
82
|
+
}
|
|
83
|
+
if (req.minEvasionTests > 0 && rule.evasionTests < req.minEvasionTests) {
|
|
84
|
+
issues.push(`only ${rule.evasionTests} evasion_test(s) (need ${req.minEvasionTests}+)`);
|
|
85
|
+
}
|
|
86
|
+
else if (rule.evasionTests < 3 && level === "experimental") {
|
|
87
|
+
warnings.push(`only ${rule.evasionTests} evasion_test(s) — recommend 3+ for stable promotion`);
|
|
88
|
+
}
|
|
89
|
+
if (req.requireOwasp && !rule.hasOwaspRef) {
|
|
90
|
+
issues.push("missing OWASP reference (LLM Top 10 or Agentic Top 10)");
|
|
91
|
+
}
|
|
92
|
+
if (req.requireMitre && !rule.hasMitreRef) {
|
|
93
|
+
issues.push("missing MITRE reference (ATLAS or ATT&CK)");
|
|
94
|
+
}
|
|
95
|
+
if (req.requireFalsePositiveDocs && !rule.hasFalsePositiveDocs) {
|
|
96
|
+
issues.push("missing false_positives documentation");
|
|
97
|
+
}
|
|
98
|
+
// Stable promotion requires human-verified provenance on key fields
|
|
99
|
+
if (req.requireHumanReviewedProvenance) {
|
|
100
|
+
const p = rule.provenance ?? {};
|
|
101
|
+
const mitreProvenance = p.mitre_atlas ?? p.mitre_attack;
|
|
102
|
+
const owaspProvenance = p.owasp_llm ?? p.owasp_agentic;
|
|
103
|
+
if (rule.hasMitreRef && mitreProvenance && !isVerified(mitreProvenance)) {
|
|
104
|
+
issues.push(`MITRE reference is "${mitreProvenance}" — stable requires human-reviewed or community-contributed`);
|
|
105
|
+
}
|
|
106
|
+
if (rule.hasOwaspRef && owaspProvenance && !isVerified(owaspProvenance)) {
|
|
107
|
+
issues.push(`OWASP reference is "${owaspProvenance}" — stable requires human-reviewed or community-contributed`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// experimental/draft: surface provenance as warning so consumers can see it
|
|
112
|
+
const p = rule.provenance ?? {};
|
|
113
|
+
const autoFields = [];
|
|
114
|
+
if (p.mitre_atlas === "auto-generated")
|
|
115
|
+
autoFields.push("mitre_atlas");
|
|
116
|
+
if (p.owasp_llm === "auto-generated")
|
|
117
|
+
autoFields.push("owasp_llm");
|
|
118
|
+
if (p.owasp_agentic === "auto-generated")
|
|
119
|
+
autoFields.push("owasp_agentic");
|
|
120
|
+
if (autoFields.length > 0) {
|
|
121
|
+
warnings.push(`auto-generated provenance on: ${autoFields.join(", ")} — needs human review for stable`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
passed: issues.length === 0,
|
|
126
|
+
issues,
|
|
127
|
+
warnings,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function isVerified(p) {
|
|
131
|
+
return VERIFIED_PROVENANCE.includes(p);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Public accessor for the requirements table.
|
|
135
|
+
* Useful for documentation generators and UIs that display the quality bar.
|
|
136
|
+
*/
|
|
137
|
+
export function getRequirements() {
|
|
138
|
+
return REQUIREMENTS;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=quality-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-gate.js","sourceRoot":"","sources":["../../src/quality/quality-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATR Quality Standard — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Vendor-neutral types for rule quality scoring and maturity validation.
|
|
5
|
+
* See docs/proposals/001-atr-quality-standard-rfc.md for the full RFC.
|
|
6
|
+
*
|
|
7
|
+
* @module agent-threat-rules/quality/types
|
|
8
|
+
*/
|
|
9
|
+
/** Rule maturity level — matches ATR schema and RFC-001 §1 */
|
|
10
|
+
export type Maturity = "draft" | "experimental" | "stable" | "deprecated";
|
|
11
|
+
/**
|
|
12
|
+
* Provenance of a metadata field.
|
|
13
|
+
* RFC-001 §4: two-dimensional compliance model.
|
|
14
|
+
*
|
|
15
|
+
* - `human-reviewed`: a human maintainer verified this mapping/content
|
|
16
|
+
* - `community-contributed`: submitted via PR by an external contributor
|
|
17
|
+
* - `auto-generated`: filled by a script or LLM without human review
|
|
18
|
+
* - `llm-generated`: produced by the TC crystallization flywheel
|
|
19
|
+
*
|
|
20
|
+
* The quality gate treats these differently:
|
|
21
|
+
* - experimental gate accepts any provenance
|
|
22
|
+
* - stable gate requires `human-reviewed` or `community-contributed`
|
|
23
|
+
*/
|
|
24
|
+
export type Provenance = "human-reviewed" | "community-contributed" | "auto-generated" | "llm-generated";
|
|
25
|
+
/**
|
|
26
|
+
* Per-field provenance tracking.
|
|
27
|
+
* Each metadata field can have its own provenance so partially-reviewed
|
|
28
|
+
* rules are represented accurately.
|
|
29
|
+
*/
|
|
30
|
+
export interface MetadataProvenance {
|
|
31
|
+
readonly mitre_atlas?: Provenance;
|
|
32
|
+
readonly mitre_attack?: Provenance;
|
|
33
|
+
readonly owasp_llm?: Provenance;
|
|
34
|
+
readonly owasp_agentic?: Provenance;
|
|
35
|
+
readonly test_cases?: Provenance;
|
|
36
|
+
readonly evasion_tests?: Provenance;
|
|
37
|
+
readonly false_positives?: Provenance;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Minimal metadata required to score and validate a rule.
|
|
41
|
+
* Any vendor's rule format can be adapted to this interface via a parser.
|
|
42
|
+
*/
|
|
43
|
+
export interface RuleMetadata {
|
|
44
|
+
/** Unique rule identifier */
|
|
45
|
+
readonly id: string;
|
|
46
|
+
/** Human-readable title */
|
|
47
|
+
readonly title: string;
|
|
48
|
+
/** Current maturity level */
|
|
49
|
+
readonly maturity: Maturity;
|
|
50
|
+
/** Number of distinct detection conditions (layers) */
|
|
51
|
+
readonly conditions: number;
|
|
52
|
+
/** Count of true_positive test cases */
|
|
53
|
+
readonly truePositives: number;
|
|
54
|
+
/** Count of true_negative test cases */
|
|
55
|
+
readonly trueNegatives: number;
|
|
56
|
+
/** Count of documented evasion tests */
|
|
57
|
+
readonly evasionTests: number;
|
|
58
|
+
/** Has at least one OWASP reference (LLM Top 10 or Agentic Top 10) */
|
|
59
|
+
readonly hasOwaspRef: boolean;
|
|
60
|
+
/** Has at least one MITRE reference (ATLAS or ATT&CK) */
|
|
61
|
+
readonly hasMitreRef: boolean;
|
|
62
|
+
/** Has at least one documented false_positive pattern */
|
|
63
|
+
readonly hasFalsePositiveDocs: boolean;
|
|
64
|
+
/** Number of real-world samples validated against this rule */
|
|
65
|
+
readonly wildSamples?: number;
|
|
66
|
+
/** Measured false positive rate on wild samples (0.0 - 100.0) */
|
|
67
|
+
readonly wildFpRate?: number;
|
|
68
|
+
/** ISO date of last wild validation run */
|
|
69
|
+
readonly wildValidatedAt?: string;
|
|
70
|
+
/** True if the rule was generated by an LLM (not human-authored) */
|
|
71
|
+
readonly llmGenerated?: boolean;
|
|
72
|
+
/** True if a human reviewer has explicitly approved this rule */
|
|
73
|
+
readonly humanReviewed?: boolean;
|
|
74
|
+
/** Per-field provenance tracking (RFC-001 §4) */
|
|
75
|
+
readonly provenance?: MetadataProvenance;
|
|
76
|
+
}
|
|
77
|
+
/** Confidence score components and total */
|
|
78
|
+
export interface ConfidenceScore {
|
|
79
|
+
/** Overall score 0-100, rounded to integer */
|
|
80
|
+
readonly total: number;
|
|
81
|
+
/** Precision component (weight 0.40) */
|
|
82
|
+
readonly precisionScore: number;
|
|
83
|
+
/** Wild validation component (weight 0.30) */
|
|
84
|
+
readonly wildValidationScore: number;
|
|
85
|
+
/** Coverage breadth component (weight 0.20) */
|
|
86
|
+
readonly coverageScore: number;
|
|
87
|
+
/** Evasion documentation component (weight 0.10) */
|
|
88
|
+
readonly evasionScore: number;
|
|
89
|
+
/** True if score was capped due to LLM-generated origin without human review */
|
|
90
|
+
readonly capped: boolean;
|
|
91
|
+
}
|
|
92
|
+
/** Result of running a rule through the quality gate */
|
|
93
|
+
export interface QualityGateResult {
|
|
94
|
+
/** True if the rule meets all required criteria for its target maturity */
|
|
95
|
+
readonly passed: boolean;
|
|
96
|
+
/** Human-readable list of gate failures (empty if passed) */
|
|
97
|
+
readonly issues: readonly string[];
|
|
98
|
+
/** Warnings that do not block promotion but should be addressed */
|
|
99
|
+
readonly warnings: readonly string[];
|
|
100
|
+
}
|
|
101
|
+
/** Decision output from canPromote() */
|
|
102
|
+
export interface PromotionDecision {
|
|
103
|
+
/** True if the rule is eligible to promote to `to` */
|
|
104
|
+
readonly eligible: boolean;
|
|
105
|
+
/** The maturity level this decision is for */
|
|
106
|
+
readonly to: Maturity;
|
|
107
|
+
/** Reasons the rule is not eligible (empty if eligible) */
|
|
108
|
+
readonly blockers: readonly string[];
|
|
109
|
+
}
|
|
110
|
+
/** A false positive report used in demotion decisions */
|
|
111
|
+
export interface FpReport {
|
|
112
|
+
/** ISO timestamp of the report */
|
|
113
|
+
readonly reportedAt: string;
|
|
114
|
+
/** Whether this report has been investigated and resolved */
|
|
115
|
+
readonly resolved: boolean;
|
|
116
|
+
}
|
|
117
|
+
/** Decision output from shouldDemote() */
|
|
118
|
+
export interface DemotionDecision {
|
|
119
|
+
/** True if the rule should be automatically demoted */
|
|
120
|
+
readonly shouldDemote: boolean;
|
|
121
|
+
/** Reasons for demotion (empty if shouldDemote is false) */
|
|
122
|
+
readonly reasons: readonly string[];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Deployment guidance based on confidence score.
|
|
126
|
+
* Maps confidence to a recommended production use.
|
|
127
|
+
*/
|
|
128
|
+
export type DeploymentRecommendation = "block-in-production" | "block-with-monitoring" | "alert-only" | "evaluation-only" | "do-not-deploy";
|
|
129
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/quality/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATR Quality Standard — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Vendor-neutral types for rule quality scoring and maturity validation.
|
|
5
|
+
* See docs/proposals/001-atr-quality-standard-rfc.md for the full RFC.
|
|
6
|
+
*
|
|
7
|
+
* @module agent-threat-rules/quality/types
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/quality/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|