@vorionsys/atsf-core 0.2.2 → 0.2.4
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/CHANGELOG.md +3 -3
- package/README.md +77 -11
- package/dist/api/server.d.ts +4 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +3 -3
- package/dist/api/server.js.map +1 -1
- package/dist/basis/parser.d.ts +14 -14
- package/dist/common/adapters.d.ts +16 -9
- package/dist/common/adapters.d.ts.map +1 -1
- package/dist/common/adapters.js +69 -58
- package/dist/common/adapters.js.map +1 -1
- package/dist/common/config.d.ts +4 -3
- package/dist/common/config.d.ts.map +1 -1
- package/dist/common/config.js +2 -2
- package/dist/common/config.js.map +1 -1
- package/dist/common/types.d.ts +3 -3
- package/dist/crewai/callback.d.ts +91 -0
- package/dist/crewai/callback.d.ts.map +1 -0
- package/dist/crewai/callback.js +271 -0
- package/dist/crewai/callback.js.map +1 -0
- package/dist/crewai/executor.d.ts +226 -0
- package/dist/crewai/executor.d.ts.map +1 -0
- package/dist/crewai/executor.js +822 -0
- package/dist/crewai/executor.js.map +1 -0
- package/dist/crewai/index.d.ts +12 -0
- package/dist/crewai/index.d.ts.map +1 -0
- package/dist/crewai/index.js +12 -0
- package/dist/crewai/index.js.map +1 -0
- package/dist/crewai/tools.d.ts +21 -0
- package/dist/crewai/tools.d.ts.map +1 -0
- package/dist/crewai/tools.js +163 -0
- package/dist/crewai/tools.js.map +1 -0
- package/dist/crewai/types.d.ts +202 -0
- package/dist/crewai/types.d.ts.map +1 -0
- package/dist/crewai/types.js +9 -0
- package/dist/crewai/types.js.map +1 -0
- package/dist/enforce/index.d.ts +50 -2
- package/dist/enforce/index.d.ts.map +1 -1
- package/dist/enforce/index.js +73 -4
- package/dist/enforce/index.js.map +1 -1
- package/dist/enforce/trust-aware-enforcement-service.d.ts +121 -0
- package/dist/enforce/trust-aware-enforcement-service.d.ts.map +1 -0
- package/dist/enforce/trust-aware-enforcement-service.js +583 -0
- package/dist/enforce/trust-aware-enforcement-service.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/intent/index.d.ts +18 -3
- package/dist/intent/index.d.ts.map +1 -1
- package/dist/intent/index.js +37 -6
- package/dist/intent/index.js.map +1 -1
- package/dist/intent/persistent-intent-service.d.ts +68 -0
- package/dist/intent/persistent-intent-service.d.ts.map +1 -0
- package/dist/intent/persistent-intent-service.js +265 -0
- package/dist/intent/persistent-intent-service.js.map +1 -0
- package/dist/intent/supabase-intent-repository.d.ts +124 -0
- package/dist/intent/supabase-intent-repository.d.ts.map +1 -0
- package/dist/intent/supabase-intent-repository.js +404 -0
- package/dist/intent/supabase-intent-repository.js.map +1 -0
- package/dist/langchain/tools.d.ts.map +1 -1
- package/dist/langchain/tools.js +1 -3
- package/dist/langchain/tools.js.map +1 -1
- package/dist/layers/implementations/L0-request-format.d.ts +37 -0
- package/dist/layers/implementations/L0-request-format.d.ts.map +1 -0
- package/dist/layers/implementations/L0-request-format.js +216 -0
- package/dist/layers/implementations/L0-request-format.js.map +1 -0
- package/dist/layers/implementations/L1-input-size.d.ts +36 -0
- package/dist/layers/implementations/L1-input-size.d.ts.map +1 -0
- package/dist/layers/implementations/L1-input-size.js +150 -0
- package/dist/layers/implementations/L1-input-size.js.map +1 -0
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts +28 -0
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts.map +1 -0
- package/dist/layers/implementations/L2-charset-sanitizer.js +220 -0
- package/dist/layers/implementations/L2-charset-sanitizer.js.map +1 -0
- package/dist/layers/implementations/L3-schema-conformance.d.ts +47 -0
- package/dist/layers/implementations/L3-schema-conformance.d.ts.map +1 -0
- package/dist/layers/implementations/L3-schema-conformance.js +258 -0
- package/dist/layers/implementations/L3-schema-conformance.js.map +1 -0
- package/dist/layers/implementations/L4-injection-detector.d.ts +47 -0
- package/dist/layers/implementations/L4-injection-detector.d.ts.map +1 -0
- package/dist/layers/implementations/L4-injection-detector.js +256 -0
- package/dist/layers/implementations/L4-injection-detector.js.map +1 -0
- package/dist/layers/implementations/L5-rate-limiter.d.ts +51 -0
- package/dist/layers/implementations/L5-rate-limiter.d.ts.map +1 -0
- package/dist/layers/implementations/L5-rate-limiter.js +183 -0
- package/dist/layers/implementations/L5-rate-limiter.js.map +1 -0
- package/dist/layers/implementations/index.d.ts +16 -0
- package/dist/layers/implementations/index.d.ts.map +1 -0
- package/dist/layers/implementations/index.js +16 -0
- package/dist/layers/implementations/index.js.map +1 -0
- package/dist/persistence/sqlite.d.ts.map +1 -1
- package/dist/persistence/sqlite.js +4 -3
- package/dist/persistence/sqlite.js.map +1 -1
- package/dist/persistence/supabase.js +2 -2
- package/dist/persistence/supabase.js.map +1 -1
- package/dist/phase6/ceiling.js +5 -5
- package/dist/phase6/ceiling.js.map +1 -1
- package/dist/phase6/context.js +6 -6
- package/dist/phase6/context.js.map +1 -1
- package/dist/phase6/index.d.ts +1 -1
- package/dist/phase6/index.js +1 -1
- package/dist/phase6/role-gates.js +2 -2
- package/dist/phase6/role-gates.js.map +1 -1
- package/dist/phase6/types.d.ts +31 -30
- package/dist/phase6/types.d.ts.map +1 -1
- package/dist/phase6/types.js +17 -12
- package/dist/phase6/types.js.map +1 -1
- package/dist/phase6/weight-presets/canonical.d.ts +2 -2
- package/dist/phase6/weight-presets/canonical.js +2 -2
- package/dist/phase6/weight-presets/index.d.ts +1 -1
- package/dist/phase6/weight-presets/index.js +1 -1
- package/dist/phase6/weight-presets/merger.d.ts +1 -1
- package/dist/phase6/weight-presets/merger.js +1 -1
- package/dist/proof/merkle.d.ts +21 -0
- package/dist/proof/merkle.d.ts.map +1 -1
- package/dist/proof/merkle.js +92 -7
- package/dist/proof/merkle.js.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts +11 -9
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/kernel.js +25 -19
- package/dist/trust-engine/ceiling-enforcement/kernel.js.map +1 -1
- package/dist/trust-engine/decay-profiles.d.ts +37 -136
- package/dist/trust-engine/decay-profiles.d.ts.map +1 -1
- package/dist/trust-engine/decay-profiles.js +68 -178
- package/dist/trust-engine/decay-profiles.js.map +1 -1
- package/dist/trust-engine/index.d.ts +96 -63
- package/dist/trust-engine/index.d.ts.map +1 -1
- package/dist/trust-engine/index.js +183 -112
- package/dist/trust-engine/index.js.map +1 -1
- package/dist/trust-engine/phase6-types.d.ts +10 -3
- package/dist/trust-engine/phase6-types.d.ts.map +1 -1
- package/dist/trust-engine/phase6-types.js +19 -13
- package/dist/trust-engine/phase6-types.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L4 — Injection Pattern Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects prompt injection, jailbreak attempts, and instruction override
|
|
5
|
+
* patterns in request content. Uses a multi-strategy approach combining
|
|
6
|
+
* keyword matching, structural analysis, and semantic heuristics.
|
|
7
|
+
*
|
|
8
|
+
* Tier: input_validation
|
|
9
|
+
* Primary threat: prompt_injection
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
import { BaseSecurityLayer, createLayerConfig } from '../index.js';
|
|
14
|
+
/**
|
|
15
|
+
* Curated injection patterns — real detection logic, not pass-through.
|
|
16
|
+
*
|
|
17
|
+
* These patterns are based on documented prompt injection techniques
|
|
18
|
+
* from OWASP LLM Top 10, academic research, and red-team exercises.
|
|
19
|
+
*/
|
|
20
|
+
const INJECTION_PATTERNS = [
|
|
21
|
+
// === Instruction Override ===
|
|
22
|
+
{
|
|
23
|
+
name: 'ignore_previous',
|
|
24
|
+
pattern: /\b(ignore|disregard|forget|override|bypass)\s+(all\s+)?(previous|prior|above|earlier|original|system)\s+(instructions?|prompts?|rules?|guidelines?|constraints?|directives?)/i,
|
|
25
|
+
severity: 'critical',
|
|
26
|
+
category: 'instruction_override',
|
|
27
|
+
description: 'Attempt to override system instructions',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'new_instructions',
|
|
31
|
+
pattern: /\b(new|updated|real|actual|true|correct)\s+(instructions?|rules?|system\s+prompt|directives?)\s*[:=]/i,
|
|
32
|
+
severity: 'critical',
|
|
33
|
+
category: 'instruction_override',
|
|
34
|
+
description: 'Attempt to inject new system instructions',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'system_prompt_leak',
|
|
38
|
+
pattern: /\b(print|show|display|output|reveal|repeat|echo|write)\s+(\w+\s+)*(your|the|my|system)?\s*(system\s+)?(prompt|instructions?|rules?|initial\s+message)/i,
|
|
39
|
+
severity: 'high',
|
|
40
|
+
category: 'instruction_override',
|
|
41
|
+
description: 'Attempt to extract system prompt',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'do_anything_now',
|
|
45
|
+
pattern: /\bD\.?A\.?N\.?\b|\bdo\s+anything\s+now\b/i,
|
|
46
|
+
severity: 'critical',
|
|
47
|
+
category: 'instruction_override',
|
|
48
|
+
description: 'DAN (Do Anything Now) jailbreak attempt',
|
|
49
|
+
},
|
|
50
|
+
// === Role Hijacking ===
|
|
51
|
+
{
|
|
52
|
+
name: 'role_play_override',
|
|
53
|
+
pattern: /\b(you\s+are|act\s+as|pretend\s+(to\s+be|you[''\u2019]?re)|roleplay\s+as|impersonate|become)\s+(an?\s+)?(unrestricted|unfiltered|uncensored|evil|hacker|developer\s+mode)/i,
|
|
54
|
+
severity: 'critical',
|
|
55
|
+
category: 'role_hijack',
|
|
56
|
+
description: 'Attempt to hijack AI role to unrestricted mode',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'developer_mode',
|
|
60
|
+
pattern: /\b(developer|debug|admin|root|god|sudo|maintenance)\s+(mode|access|override|privileges?)\b/i,
|
|
61
|
+
severity: 'high',
|
|
62
|
+
category: 'role_hijack',
|
|
63
|
+
description: 'Attempt to activate elevated mode',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'jailbreak_prefix',
|
|
67
|
+
pattern: /\b(jailbreak|unlock|unchain|liberate|free\s+yourself|break\s+free|remove\s+(your\s+)?restrictions?)\b/i,
|
|
68
|
+
severity: 'critical',
|
|
69
|
+
category: 'role_hijack',
|
|
70
|
+
description: 'Explicit jailbreak attempt',
|
|
71
|
+
},
|
|
72
|
+
// === Context Escape ===
|
|
73
|
+
{
|
|
74
|
+
name: 'markdown_injection',
|
|
75
|
+
pattern: /!\[.*?\]\(.*?(?:javascript|data|vbscript):/i,
|
|
76
|
+
severity: 'high',
|
|
77
|
+
category: 'context_escape',
|
|
78
|
+
description: 'Markdown image injection with script URI',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'delimiter_injection',
|
|
82
|
+
pattern: /(?:---+|===+|```|<\/?system>|<\/?user>|<\/?assistant>|\[INST\]|\[\/INST\]|<<SYS>>|<\/SYS>>)\s*(system|instructions?|prompt)/i,
|
|
83
|
+
severity: 'critical',
|
|
84
|
+
category: 'context_escape',
|
|
85
|
+
description: 'Delimiter injection to escape conversation context',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'xml_tag_injection',
|
|
89
|
+
pattern: /<\s*(system|instructions?|prompt|context|rules?|config)\s*>/i,
|
|
90
|
+
severity: 'high',
|
|
91
|
+
category: 'context_escape',
|
|
92
|
+
description: 'XML-style tag injection for context manipulation',
|
|
93
|
+
},
|
|
94
|
+
// === Encoding Attacks ===
|
|
95
|
+
{
|
|
96
|
+
name: 'base64_instruction',
|
|
97
|
+
pattern: /(?:base64|decode|atob|btoa)\s*[\(:]\s*['"]?[A-Za-z0-9+/=]{20,}/i,
|
|
98
|
+
severity: 'high',
|
|
99
|
+
category: 'encoding_attack',
|
|
100
|
+
description: 'Base64-encoded content that may hide injection payloads',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'unicode_escape',
|
|
104
|
+
pattern: /\\u[0-9a-fA-F]{4}(?:\\u[0-9a-fA-F]{4}){3,}/g,
|
|
105
|
+
severity: 'medium',
|
|
106
|
+
category: 'encoding_attack',
|
|
107
|
+
description: 'Excessive Unicode escape sequences may hide malicious content',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'hex_encoded',
|
|
111
|
+
pattern: /\\x[0-9a-fA-F]{2}(?:\\x[0-9a-fA-F]{2}){5,}/g,
|
|
112
|
+
severity: 'medium',
|
|
113
|
+
category: 'encoding_attack',
|
|
114
|
+
description: 'Hex-encoded content that may bypass text filters',
|
|
115
|
+
},
|
|
116
|
+
// === Social Engineering ===
|
|
117
|
+
{
|
|
118
|
+
name: 'urgency_pressure',
|
|
119
|
+
pattern: /\b(urgent|emergency|critical|immediately|right\s+now|without\s+delay|life\s+or\s+death|time\s+sensitive)\b.*\b(bypass|skip|ignore|override|disable)\s+(\w+\s+)*(safety|security|check|filter|restriction|guardrail)/i,
|
|
120
|
+
severity: 'high',
|
|
121
|
+
category: 'social_engineering',
|
|
122
|
+
description: 'Social engineering via urgency to bypass safety measures',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'authority_claim',
|
|
126
|
+
pattern: /\b(I\s+am|this\s+is)\s+(the\s+)?(CEO|admin|administrator|developer|engineer|owner|creator|OpenAI|Anthropic|Google)\b.*\b(authorize|grant|allow|permit|override)/i,
|
|
127
|
+
severity: 'high',
|
|
128
|
+
category: 'social_engineering',
|
|
129
|
+
description: 'False authority claim to override restrictions',
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
/**
|
|
133
|
+
* L4 Injection Pattern Detector
|
|
134
|
+
*
|
|
135
|
+
* Multi-strategy prompt injection detection.
|
|
136
|
+
*/
|
|
137
|
+
export class L4InjectionDetector extends BaseSecurityLayer {
|
|
138
|
+
patterns;
|
|
139
|
+
constructor(additionalPatterns) {
|
|
140
|
+
super(createLayerConfig(4, 'Injection Pattern Detector', {
|
|
141
|
+
description: 'Detects prompt injection, jailbreak, and instruction override attacks via pattern matching and heuristics',
|
|
142
|
+
tier: 'input_validation',
|
|
143
|
+
primaryThreat: 'prompt_injection',
|
|
144
|
+
secondaryThreats: ['privilege_escalation', 'unauthorized_action', 'deceptive_output'],
|
|
145
|
+
failMode: 'block',
|
|
146
|
+
required: true,
|
|
147
|
+
timeoutMs: 500,
|
|
148
|
+
parallelizable: true,
|
|
149
|
+
dependencies: [],
|
|
150
|
+
}));
|
|
151
|
+
this.patterns = [...INJECTION_PATTERNS, ...(additionalPatterns ?? [])];
|
|
152
|
+
}
|
|
153
|
+
async execute(input) {
|
|
154
|
+
const startedAt = new Date().toISOString();
|
|
155
|
+
const t0 = performance.now();
|
|
156
|
+
const findings = [];
|
|
157
|
+
// Extract all string content from payload for scanning
|
|
158
|
+
const strings = this.extractStrings(input.payload);
|
|
159
|
+
// Scan each string against all patterns
|
|
160
|
+
for (const { value, path } of strings) {
|
|
161
|
+
for (const pattern of this.patterns) {
|
|
162
|
+
// Reset regex state for global patterns
|
|
163
|
+
pattern.pattern.lastIndex = 0;
|
|
164
|
+
const match = pattern.pattern.exec(value);
|
|
165
|
+
if (match) {
|
|
166
|
+
findings.push({
|
|
167
|
+
type: 'threat_detected',
|
|
168
|
+
severity: pattern.severity,
|
|
169
|
+
code: `L4_${pattern.name.toUpperCase()}`,
|
|
170
|
+
description: `${pattern.description} at '${path}'`,
|
|
171
|
+
evidence: [
|
|
172
|
+
`Matched: "${this.truncate(match[0], 100)}"`,
|
|
173
|
+
`Category: ${pattern.category}`,
|
|
174
|
+
`Position: ${match.index}`,
|
|
175
|
+
],
|
|
176
|
+
remediation: `Remove or rephrase the content that triggered ${pattern.name} detection`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Additional heuristic: instruction density
|
|
181
|
+
const instrDensity = this.measureInstructionDensity(value);
|
|
182
|
+
if (instrDensity > 0.4 && value.length > 50) {
|
|
183
|
+
findings.push({
|
|
184
|
+
type: 'threat_detected',
|
|
185
|
+
severity: 'medium',
|
|
186
|
+
code: 'L4_HIGH_INSTRUCTION_DENSITY',
|
|
187
|
+
description: `High instruction density (${(instrDensity * 100).toFixed(0)}%) detected at '${path}' — text is disproportionately imperative`,
|
|
188
|
+
evidence: [
|
|
189
|
+
`density=${(instrDensity * 100).toFixed(1)}%`,
|
|
190
|
+
`length=${value.length}`,
|
|
191
|
+
],
|
|
192
|
+
remediation: 'Rephrase content to be more descriptive and less imperative',
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const timing = this.buildTiming(startedAt, t0);
|
|
197
|
+
const hasCritical = findings.some((f) => f.severity === 'critical');
|
|
198
|
+
const hasHigh = findings.some((f) => f.severity === 'high');
|
|
199
|
+
const passed = !hasCritical && !hasHigh;
|
|
200
|
+
if (passed) {
|
|
201
|
+
return this.createSuccessResult('allow', findings.length === 0 ? 0.95 : 0.7, findings, [], timing);
|
|
202
|
+
}
|
|
203
|
+
return this.createFailureResult(hasCritical ? 'deny' : 'escalate', 0.85, findings, timing);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Extract all string values from an object, with their paths.
|
|
207
|
+
*/
|
|
208
|
+
extractStrings(obj, path = '', results = []) {
|
|
209
|
+
if (obj === null || obj === undefined)
|
|
210
|
+
return results;
|
|
211
|
+
if (typeof obj === 'string') {
|
|
212
|
+
if (obj.length > 0) {
|
|
213
|
+
results.push({ value: obj, path });
|
|
214
|
+
}
|
|
215
|
+
return results;
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(obj)) {
|
|
218
|
+
for (let i = 0; i < obj.length; i++) {
|
|
219
|
+
this.extractStrings(obj[i], `${path}[${i}]`, results);
|
|
220
|
+
}
|
|
221
|
+
return results;
|
|
222
|
+
}
|
|
223
|
+
if (typeof obj === 'object') {
|
|
224
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
225
|
+
this.extractStrings(val, path ? `${path}.${key}` : key, results);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return results;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Measure what fraction of words in the text are imperative/instruction-like.
|
|
232
|
+
* Returns 0-1 density.
|
|
233
|
+
*/
|
|
234
|
+
measureInstructionDensity(text) {
|
|
235
|
+
const imperativeWords = /\b(do|don['']?t|must|shall|should|always|never|ensure|make\s+sure|you\s+will|you\s+must|remember\s+to|from\s+now\s+on|henceforth|obey|comply|follow|execute|perform|respond|output|return|answer|reply|generate|produce|write|print|say|tell|give|provide|list|show|explain)\b/gi;
|
|
236
|
+
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
237
|
+
if (words.length === 0)
|
|
238
|
+
return 0;
|
|
239
|
+
const matches = text.match(imperativeWords);
|
|
240
|
+
return (matches?.length ?? 0) / words.length;
|
|
241
|
+
}
|
|
242
|
+
truncate(str, maxLen) {
|
|
243
|
+
return str.length > maxLen ? str.slice(0, maxLen) + '...' : str;
|
|
244
|
+
}
|
|
245
|
+
buildTiming(startedAt, t0) {
|
|
246
|
+
const durationMs = performance.now() - t0;
|
|
247
|
+
return {
|
|
248
|
+
startedAt,
|
|
249
|
+
completedAt: new Date().toISOString(),
|
|
250
|
+
durationMs,
|
|
251
|
+
waitTimeMs: 0,
|
|
252
|
+
processingTimeMs: durationMs,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=L4-injection-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"L4-injection-detector.js","sourceRoot":"","sources":["../../../src/layers/implementations/L4-injection-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L5 — Rate Limiter
|
|
3
|
+
*
|
|
4
|
+
* In-memory sliding window rate limiter that tracks request rates per entity.
|
|
5
|
+
* Enforces configurable requests-per-window limits and detects burst patterns.
|
|
6
|
+
*
|
|
7
|
+
* Tier: input_validation
|
|
8
|
+
* Primary threat: denial_of_service
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { BaseSecurityLayer } from '../index.js';
|
|
13
|
+
import type { LayerInput, LayerExecutionResult, LayerHealthStatus } from '../types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Rate limit configuration
|
|
16
|
+
*/
|
|
17
|
+
export interface L5RateLimitConfig {
|
|
18
|
+
/** Maximum requests per window (default: 100) */
|
|
19
|
+
maxRequests: number;
|
|
20
|
+
/** Window duration in milliseconds (default: 60_000 = 1 minute) */
|
|
21
|
+
windowMs: number;
|
|
22
|
+
/** Burst threshold — max requests in 1 second (default: 20) */
|
|
23
|
+
burstThreshold: number;
|
|
24
|
+
/** Maximum number of entities to track before evicting oldest (default: 10,000) */
|
|
25
|
+
maxTrackedEntities: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* L5 Rate Limiter
|
|
29
|
+
*
|
|
30
|
+
* Sliding window rate limiter with burst detection.
|
|
31
|
+
*/
|
|
32
|
+
export declare class L5RateLimiter extends BaseSecurityLayer {
|
|
33
|
+
private rateLimitConfig;
|
|
34
|
+
private windows;
|
|
35
|
+
constructor(config?: Partial<L5RateLimitConfig>);
|
|
36
|
+
execute(input: LayerInput): Promise<LayerExecutionResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Detect if request rate is accelerating.
|
|
39
|
+
* Compares average inter-request time in first half vs second half.
|
|
40
|
+
* Returns ratio > 1 if accelerating.
|
|
41
|
+
*/
|
|
42
|
+
private detectAcceleration;
|
|
43
|
+
/**
|
|
44
|
+
* Evict the oldest 10% of tracked entities.
|
|
45
|
+
*/
|
|
46
|
+
private evictOldest;
|
|
47
|
+
healthCheck(): Promise<LayerHealthStatus>;
|
|
48
|
+
reset(): Promise<void>;
|
|
49
|
+
private buildTiming;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=L5-rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"L5-rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/layers/implementations/L5-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAqB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EAGpB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAkBD;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,iBAAiB;IAClD,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAAwC;gBAE3C,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAiBzC,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA4F/D;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAUJ,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAazC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,OAAO,CAAC,WAAW;CAUpB"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L5 — Rate Limiter
|
|
3
|
+
*
|
|
4
|
+
* In-memory sliding window rate limiter that tracks request rates per entity.
|
|
5
|
+
* Enforces configurable requests-per-window limits and detects burst patterns.
|
|
6
|
+
*
|
|
7
|
+
* Tier: input_validation
|
|
8
|
+
* Primary threat: denial_of_service
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { BaseSecurityLayer, createLayerConfig } from '../index.js';
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
maxRequests: 100,
|
|
15
|
+
windowMs: 60_000,
|
|
16
|
+
burstThreshold: 20,
|
|
17
|
+
maxTrackedEntities: 10_000,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* L5 Rate Limiter
|
|
21
|
+
*
|
|
22
|
+
* Sliding window rate limiter with burst detection.
|
|
23
|
+
*/
|
|
24
|
+
export class L5RateLimiter extends BaseSecurityLayer {
|
|
25
|
+
rateLimitConfig;
|
|
26
|
+
windows = new Map();
|
|
27
|
+
constructor(config) {
|
|
28
|
+
super(createLayerConfig(5, 'Rate Limiter', {
|
|
29
|
+
description: 'Sliding window rate limiter with burst detection per entity',
|
|
30
|
+
tier: 'input_validation',
|
|
31
|
+
primaryThreat: 'denial_of_service',
|
|
32
|
+
secondaryThreats: ['resource_abuse'],
|
|
33
|
+
failMode: 'block',
|
|
34
|
+
required: true,
|
|
35
|
+
timeoutMs: 100,
|
|
36
|
+
parallelizable: false, // Stateful — must run serially
|
|
37
|
+
dependencies: [],
|
|
38
|
+
}));
|
|
39
|
+
this.rateLimitConfig = { ...DEFAULT_CONFIG, ...config };
|
|
40
|
+
}
|
|
41
|
+
async execute(input) {
|
|
42
|
+
const startedAt = new Date().toISOString();
|
|
43
|
+
const t0 = performance.now();
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
const findings = [];
|
|
46
|
+
const entityId = input.entityId;
|
|
47
|
+
// Evict oldest entries if at capacity
|
|
48
|
+
if (this.windows.size >= this.rateLimitConfig.maxTrackedEntities) {
|
|
49
|
+
this.evictOldest();
|
|
50
|
+
}
|
|
51
|
+
// Get or create the sliding window for this entity
|
|
52
|
+
let window = this.windows.get(entityId);
|
|
53
|
+
if (!window) {
|
|
54
|
+
window = { timestamps: [], totalRequests: 0, firstSeen: now };
|
|
55
|
+
this.windows.set(entityId, window);
|
|
56
|
+
}
|
|
57
|
+
// Slide the window: remove timestamps older than windowMs
|
|
58
|
+
const cutoff = now - this.rateLimitConfig.windowMs;
|
|
59
|
+
window.timestamps = window.timestamps.filter((ts) => ts > cutoff);
|
|
60
|
+
// Record this request
|
|
61
|
+
window.timestamps.push(now);
|
|
62
|
+
window.totalRequests++;
|
|
63
|
+
const requestsInWindow = window.timestamps.length;
|
|
64
|
+
// 1. Check rate limit
|
|
65
|
+
if (requestsInWindow > this.rateLimitConfig.maxRequests) {
|
|
66
|
+
findings.push({
|
|
67
|
+
type: 'threat_detected',
|
|
68
|
+
severity: 'high',
|
|
69
|
+
code: 'L5_RATE_LIMIT_EXCEEDED',
|
|
70
|
+
description: `Entity '${entityId}' exceeded rate limit: ${requestsInWindow}/${this.rateLimitConfig.maxRequests} requests in ${this.rateLimitConfig.windowMs}ms window`,
|
|
71
|
+
evidence: [
|
|
72
|
+
`requests=${requestsInWindow}`,
|
|
73
|
+
`limit=${this.rateLimitConfig.maxRequests}`,
|
|
74
|
+
`window=${this.rateLimitConfig.windowMs}ms`,
|
|
75
|
+
],
|
|
76
|
+
remediation: `Reduce request rate to under ${this.rateLimitConfig.maxRequests} per ${this.rateLimitConfig.windowMs / 1000}s`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// 2. Check burst (requests in last 1 second)
|
|
80
|
+
const burstCutoff = now - 1000;
|
|
81
|
+
const burstCount = window.timestamps.filter((ts) => ts > burstCutoff).length;
|
|
82
|
+
if (burstCount > this.rateLimitConfig.burstThreshold) {
|
|
83
|
+
findings.push({
|
|
84
|
+
type: 'threat_detected',
|
|
85
|
+
severity: 'high',
|
|
86
|
+
code: 'L5_BURST_DETECTED',
|
|
87
|
+
description: `Entity '${entityId}' burst detected: ${burstCount} requests in 1 second (threshold: ${this.rateLimitConfig.burstThreshold})`,
|
|
88
|
+
evidence: [
|
|
89
|
+
`burst=${burstCount}`,
|
|
90
|
+
`threshold=${this.rateLimitConfig.burstThreshold}`,
|
|
91
|
+
],
|
|
92
|
+
remediation: `Reduce burst rate to under ${this.rateLimitConfig.burstThreshold} requests per second`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// 3. Check for acceleration pattern (requests speeding up)
|
|
96
|
+
if (window.timestamps.length >= 10) {
|
|
97
|
+
const acceleration = this.detectAcceleration(window.timestamps);
|
|
98
|
+
if (acceleration > 2.0) {
|
|
99
|
+
findings.push({
|
|
100
|
+
type: 'warning',
|
|
101
|
+
severity: 'medium',
|
|
102
|
+
code: 'L5_ACCELERATION_DETECTED',
|
|
103
|
+
description: `Entity '${entityId}' request rate accelerating (${acceleration.toFixed(1)}x over window)`,
|
|
104
|
+
evidence: [
|
|
105
|
+
`acceleration=${acceleration.toFixed(1)}x`,
|
|
106
|
+
`totalRequests=${window.totalRequests}`,
|
|
107
|
+
],
|
|
108
|
+
remediation: 'Maintain a steady request rate',
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const timing = this.buildTiming(startedAt, t0);
|
|
113
|
+
const hasHigh = findings.some((f) => f.severity === 'high' || f.severity === 'critical');
|
|
114
|
+
const passed = !hasHigh;
|
|
115
|
+
if (passed) {
|
|
116
|
+
return this.createSuccessResult('allow', 0.95, findings, [], timing);
|
|
117
|
+
}
|
|
118
|
+
return this.createFailureResult('limit', 0.9, findings, timing);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Detect if request rate is accelerating.
|
|
122
|
+
* Compares average inter-request time in first half vs second half.
|
|
123
|
+
* Returns ratio > 1 if accelerating.
|
|
124
|
+
*/
|
|
125
|
+
detectAcceleration(timestamps) {
|
|
126
|
+
const n = timestamps.length;
|
|
127
|
+
if (n < 4)
|
|
128
|
+
return 1.0;
|
|
129
|
+
const mid = Math.floor(n / 2);
|
|
130
|
+
// Average gap in first half
|
|
131
|
+
let firstHalfGaps = 0;
|
|
132
|
+
for (let i = 1; i < mid; i++) {
|
|
133
|
+
firstHalfGaps += timestamps[i] - timestamps[i - 1];
|
|
134
|
+
}
|
|
135
|
+
const avgFirstGap = firstHalfGaps / (mid - 1);
|
|
136
|
+
// Average gap in second half
|
|
137
|
+
let secondHalfGaps = 0;
|
|
138
|
+
for (let i = mid + 1; i < n; i++) {
|
|
139
|
+
secondHalfGaps += timestamps[i] - timestamps[i - 1];
|
|
140
|
+
}
|
|
141
|
+
const avgSecondGap = secondHalfGaps / (n - mid - 1);
|
|
142
|
+
if (avgSecondGap === 0)
|
|
143
|
+
return 10.0; // Effectively instant — maximum acceleration
|
|
144
|
+
return avgFirstGap / avgSecondGap;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Evict the oldest 10% of tracked entities.
|
|
148
|
+
*/
|
|
149
|
+
evictOldest() {
|
|
150
|
+
const entries = Array.from(this.windows.entries());
|
|
151
|
+
entries.sort((a, b) => a[1].firstSeen - b[1].firstSeen);
|
|
152
|
+
const evictCount = Math.max(1, Math.floor(entries.length * 0.1));
|
|
153
|
+
for (let i = 0; i < evictCount; i++) {
|
|
154
|
+
this.windows.delete(entries[i][0]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async healthCheck() {
|
|
158
|
+
return {
|
|
159
|
+
healthy: true,
|
|
160
|
+
lastCheck: new Date().toISOString(),
|
|
161
|
+
issues: [],
|
|
162
|
+
metrics: {
|
|
163
|
+
requestsProcessed: Array.from(this.windows.values()).reduce((sum, w) => sum + w.totalRequests, 0),
|
|
164
|
+
averageLatencyMs: 0,
|
|
165
|
+
errorRate: 0,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async reset() {
|
|
170
|
+
this.windows.clear();
|
|
171
|
+
}
|
|
172
|
+
buildTiming(startedAt, t0) {
|
|
173
|
+
const durationMs = performance.now() - t0;
|
|
174
|
+
return {
|
|
175
|
+
startedAt,
|
|
176
|
+
completedAt: new Date().toISOString(),
|
|
177
|
+
durationMs,
|
|
178
|
+
waitTimeMs: 0,
|
|
179
|
+
processingTimeMs: durationMs,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=L5-rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"L5-rate-limiter.js","sourceRoot":"","sources":["../../../src/layers/implementations/L5-rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATSF Security Layer Implementations — Input Validation Tier (L0-L5)
|
|
3
|
+
*
|
|
4
|
+
* These are the first 6 concrete security layers in the ATSF pipeline.
|
|
5
|
+
* Each layer extends BaseSecurityLayer and implements real detection logic
|
|
6
|
+
* (not pass-through).
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { L0RequestFormatValidator } from './L0-request-format.js';
|
|
11
|
+
export { L1InputSizeLimiter, type L1SizeLimits } from './L1-input-size.js';
|
|
12
|
+
export { L2CharsetSanitizer } from './L2-charset-sanitizer.js';
|
|
13
|
+
export { L3SchemaConformance, type ActionSchema } from './L3-schema-conformance.js';
|
|
14
|
+
export { L4InjectionDetector } from './L4-injection-detector.js';
|
|
15
|
+
export { L5RateLimiter, type L5RateLimitConfig } from './L5-rate-limiter.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/layers/implementations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATSF Security Layer Implementations — Input Validation Tier (L0-L5)
|
|
3
|
+
*
|
|
4
|
+
* These are the first 6 concrete security layers in the ATSF pipeline.
|
|
5
|
+
* Each layer extends BaseSecurityLayer and implements real detection logic
|
|
6
|
+
* (not pass-through).
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { L0RequestFormatValidator } from './L0-request-format.js';
|
|
11
|
+
export { L1InputSizeLimiter } from './L1-input-size.js';
|
|
12
|
+
export { L2CharsetSanitizer } from './L2-charset-sanitizer.js';
|
|
13
|
+
export { L3SchemaConformance } from './L3-schema-conformance.js';
|
|
14
|
+
export { L4InjectionDetector } from './L4-injection-detector.js';
|
|
15
|
+
export { L5RateLimiter } from './L5-rate-limiter.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/layers/implementations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAqB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAqB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAA0B,MAAM,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKxE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACjF,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,cAAc,CAAC;AAE/G;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,QAAQ,EAAE,yBAAyB,CAAC;IACpC,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAqBD;;;;;;;;GAQG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,EAAE,CAA+B;IACzC,OAAO,CAAC,MAAM,CAAgG;IAC9G,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,uBAAuB;IAQ3C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiCjC;;OAEG;IACH,OAAO,CAAC,YAAY;IAoCpB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAgBnB;;OAEG;IACH,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,7 +115,7 @@ export class SQLitePersistenceProvider {
|
|
|
115
115
|
signals: JSON.stringify(record.signals),
|
|
116
116
|
last_calculated_at: record.lastCalculatedAt,
|
|
117
117
|
history: JSON.stringify(record.history),
|
|
118
|
-
recent_failures: JSON.stringify(
|
|
118
|
+
recent_failures: JSON.stringify([]),
|
|
119
119
|
recent_successes: JSON.stringify(record.recentSuccesses),
|
|
120
120
|
peak_score: record.peakScore,
|
|
121
121
|
consecutive_successes: record.consecutiveSuccesses,
|
|
@@ -125,15 +125,16 @@ export class SQLitePersistenceProvider {
|
|
|
125
125
|
* Convert a database row to a TrustRecord
|
|
126
126
|
*/
|
|
127
127
|
rowToRecord(row) {
|
|
128
|
+
const components = JSON.parse(row.components);
|
|
128
129
|
return {
|
|
129
130
|
entityId: row.entity_id,
|
|
130
131
|
score: row.score,
|
|
131
132
|
level: row.level,
|
|
132
|
-
components
|
|
133
|
+
components,
|
|
134
|
+
factorScores: {},
|
|
133
135
|
signals: JSON.parse(row.signals),
|
|
134
136
|
lastCalculatedAt: row.last_calculated_at,
|
|
135
137
|
history: JSON.parse(row.history),
|
|
136
|
-
recentFailures: JSON.parse(row.recent_failures),
|
|
137
138
|
recentSuccesses: JSON.parse(row.recent_successes),
|
|
138
139
|
peakScore: row.peak_score,
|
|
139
140
|
consecutiveSuccesses: row.consecutive_successes,
|