tryassay 0.33.2 → 0.35.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/dist/bayesian/__tests__/bas-calculator.test.d.ts +1 -0
- package/dist/bayesian/__tests__/bas-calculator.test.js +63 -0
- package/dist/bayesian/__tests__/bas-calculator.test.js.map +1 -0
- package/dist/bayesian/__tests__/structural-entropy.test.d.ts +1 -0
- package/dist/bayesian/__tests__/structural-entropy.test.js +21 -0
- package/dist/bayesian/__tests__/structural-entropy.test.js.map +1 -0
- package/dist/bayesian/bas-calculator.d.ts +41 -0
- package/dist/bayesian/bas-calculator.js +198 -0
- package/dist/bayesian/bas-calculator.js.map +1 -0
- package/dist/bayesian/index.d.ts +3 -0
- package/dist/bayesian/index.js +3 -0
- package/dist/bayesian/index.js.map +1 -0
- package/dist/bayesian/structural-entropy.d.ts +12 -0
- package/dist/bayesian/structural-entropy.js +37 -0
- package/dist/bayesian/structural-entropy.js.map +1 -0
- package/dist/bayesian/types.d.ts +37 -0
- package/dist/bayesian/types.js +6 -0
- package/dist/bayesian/types.js.map +1 -0
- package/dist/cli.js +46 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/assess-formal.test.d.ts +1 -0
- package/dist/commands/__tests__/assess-formal.test.js +72 -0
- package/dist/commands/__tests__/assess-formal.test.js.map +1 -0
- package/dist/commands/activate.d.ts +1 -0
- package/dist/commands/activate.js +48 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/assess.js +100 -5
- package/dist/commands/assess.js.map +1 -1
- package/dist/commands/bas-score.d.ts +13 -0
- package/dist/commands/bas-score.js +310 -0
- package/dist/commands/bas-score.js.map +1 -0
- package/dist/commands/bounty-watch.js.map +1 -1
- package/dist/commands/hunt.js +32 -0
- package/dist/commands/hunt.js.map +1 -1
- package/dist/commands/mcp.d.ts +14 -0
- package/dist/commands/mcp.js +18 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/runtime.js +11 -10
- package/dist/commands/runtime.js.map +1 -1
- package/dist/commands/stream-verify.d.ts +16 -0
- package/dist/commands/stream-verify.js +228 -0
- package/dist/commands/stream-verify.js.map +1 -0
- package/dist/commands/watch.d.ts +19 -0
- package/dist/commands/watch.js +158 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/hunt/__tests__/deep-dive.test.js.map +1 -1
- package/dist/hunt/__tests__/e2e.test.js.map +1 -1
- package/dist/hunt/__tests__/finding-to-template.test.js +10 -1
- package/dist/hunt/__tests__/finding-to-template.test.js.map +1 -1
- package/dist/hunt/__tests__/orchestrator.test.js.map +1 -1
- package/dist/hunt/__tests__/templates.test.js +2 -2
- package/dist/hunt/__tests__/triage.test.js.map +1 -1
- package/dist/hunt/deep-dive.js +7 -7
- package/dist/hunt/deep-dive.js.map +1 -1
- package/dist/hunt/parse-utils.d.ts +1 -1
- package/dist/hunt/state.js.map +1 -1
- package/dist/hunt/templates/injection.js +1 -1
- package/dist/hunt/templates/injection.js.map +1 -1
- package/dist/hunt/triage.js +5 -5
- package/dist/hunt/triage.js.map +1 -1
- package/dist/lib/__tests__/arithmetic-quick-test.js +10 -9
- package/dist/lib/__tests__/arithmetic-quick-test.js.map +1 -1
- package/dist/lib/__tests__/arithmetic-real-llm-test.js +8 -8
- package/dist/lib/__tests__/arithmetic-real-llm-test.js.map +1 -1
- package/dist/lib/__tests__/formal-verifier-behavioral.test.d.ts +18 -0
- package/dist/lib/__tests__/formal-verifier-behavioral.test.js +576 -0
- package/dist/lib/__tests__/formal-verifier-behavioral.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.js +154 -0
- package/dist/lib/__tests__/formal-verifier-claimless-async.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.js +121 -0
- package/dist/lib/__tests__/formal-verifier-claimless-quality.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.js +119 -0
- package/dist/lib/__tests__/formal-verifier-claimless-realworld.test.js.map +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.d.ts +1 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.js +667 -0
- package/dist/lib/__tests__/formal-verifier-claimless.test.js.map +1 -0
- package/dist/lib/__tests__/mr-gsm8k-benchmark.js +6 -6
- package/dist/lib/__tests__/mr-gsm8k-benchmark.js.map +1 -1
- package/dist/lib/__tests__/pr-harvester.test.js.map +1 -1
- package/dist/lib/assessment-reporter.d.ts +1 -1
- package/dist/lib/assessment-reporter.js +2 -1
- package/dist/lib/assessment-reporter.js.map +1 -1
- package/dist/lib/chain-analyzer.d.ts +4 -3
- package/dist/lib/chain-analyzer.js.map +1 -1
- package/dist/lib/formal-verifier.d.ts +20 -1
- package/dist/lib/formal-verifier.js +1180 -23
- package/dist/lib/formal-verifier.js.map +1 -1
- package/dist/lib/issue-reporter.d.ts +2 -1
- package/dist/lib/issue-reporter.js.map +1 -1
- package/dist/lib/remediation-generator.js.map +1 -1
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/rule-harvester/ground-truth.js +13 -2
- package/dist/lib/rule-harvester/ground-truth.js.map +1 -1
- package/dist/lib/rule-harvester/scanner.d.ts +1 -1
- package/dist/lib/user-config.d.ts +1 -0
- package/dist/lib/user-config.js.map +1 -1
- package/dist/realtime/__tests__/catch-real-bugs.test.d.ts +9 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js +205 -0
- package/dist/realtime/__tests__/catch-real-bugs.test.js.map +1 -0
- package/dist/realtime/__tests__/code-buffer.test.d.ts +1 -0
- package/dist/realtime/__tests__/code-buffer.test.js +202 -0
- package/dist/realtime/__tests__/code-buffer.test.js.map +1 -0
- package/dist/realtime/__tests__/correction-injector.test.d.ts +1 -0
- package/dist/realtime/__tests__/correction-injector.test.js +168 -0
- package/dist/realtime/__tests__/correction-injector.test.js.map +1 -0
- package/dist/realtime/__tests__/entropy-detector.test.d.ts +1 -0
- package/dist/realtime/__tests__/entropy-detector.test.js +200 -0
- package/dist/realtime/__tests__/entropy-detector.test.js.map +1 -0
- package/dist/realtime/__tests__/entropy-live-demo.d.ts +1 -0
- package/dist/realtime/__tests__/entropy-live-demo.js +103 -0
- package/dist/realtime/__tests__/entropy-live-demo.js.map +1 -0
- package/dist/realtime/__tests__/entropy-live.d.ts +8 -0
- package/dist/realtime/__tests__/entropy-live.js +114 -0
- package/dist/realtime/__tests__/entropy-live.js.map +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.d.ts +1 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js +193 -0
- package/dist/realtime/__tests__/stream-interceptor.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-checks.test.js +478 -0
- package/dist/realtime/__tests__/streaming-checks.test.js.map +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.d.ts +1 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js +157 -0
- package/dist/realtime/__tests__/streaming-verifier.test.js.map +1 -0
- package/dist/realtime/code-buffer.d.ts +52 -0
- package/dist/realtime/code-buffer.js +276 -0
- package/dist/realtime/code-buffer.js.map +1 -0
- package/dist/realtime/correction-injector.d.ts +56 -0
- package/dist/realtime/correction-injector.js +96 -0
- package/dist/realtime/correction-injector.js.map +1 -0
- package/dist/realtime/entropy-detector.d.ts +143 -0
- package/dist/realtime/entropy-detector.js +504 -0
- package/dist/realtime/entropy-detector.js.map +1 -0
- package/dist/realtime/index.d.ts +14 -0
- package/dist/realtime/index.js +11 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/mcp-server.d.ts +20 -0
- package/dist/realtime/mcp-server.js +576 -0
- package/dist/realtime/mcp-server.js.map +1 -0
- package/dist/realtime/stream-interceptor.d.ts +93 -0
- package/dist/realtime/stream-interceptor.js +378 -0
- package/dist/realtime/stream-interceptor.js.map +1 -0
- package/dist/realtime/streaming-checks.d.ts +55 -0
- package/dist/realtime/streaming-checks.js +480 -0
- package/dist/realtime/streaming-checks.js.map +1 -0
- package/dist/realtime/streaming-verifier.d.ts +102 -0
- package/dist/realtime/streaming-verifier.js +227 -0
- package/dist/realtime/streaming-verifier.js.map +1 -0
- package/dist/realtime/types.d.ts +155 -0
- package/dist/realtime/types.js +8 -0
- package/dist/realtime/types.js.map +1 -0
- package/dist/runtime/agents/research-agent.js +10 -1
- package/dist/runtime/agents/research-agent.js.map +1 -1
- package/dist/runtime/agents/test-agent.js +10 -7
- package/dist/runtime/agents/test-agent.js.map +1 -1
- package/dist/runtime/composition-verifier.js +13 -3
- package/dist/runtime/composition-verifier.js.map +1 -1
- package/dist/runtime/fs-helpers.js.map +1 -1
- package/dist/runtime/prompt-safety-analyzer.js.map +1 -1
- package/dist/sdk/verified-generate.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/package.json +4 -2
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming Checks — stateless, pre-compiled pattern matchers for real-time verification.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the regex-based formal verification checks from the existing
|
|
5
|
+
* formal-verifier.ts into standalone StreamingCheck objects. Also loads
|
|
6
|
+
* learned rules from the catalog and compiles them into the same format.
|
|
7
|
+
*
|
|
8
|
+
* All regex patterns are created once at module load time and reused across
|
|
9
|
+
* invocations. The `runChecks` function targets <10ms for the full check set
|
|
10
|
+
* against a single code unit.
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
// ── Formal Checks (hand-crafted) ────────────────────────────────
|
|
15
|
+
const JS_LANGS = ['typescript', 'javascript', 'ts', 'js', 'tsx', 'jsx'];
|
|
16
|
+
const PY_LANGS = ['python', 'py'];
|
|
17
|
+
const ALL_LANGS = []; // empty = applies to all
|
|
18
|
+
/**
|
|
19
|
+
* Libraries that use tagged template literals for SQL parameterization.
|
|
20
|
+
* When these imports are detected, template literal SQL checks are suppressed
|
|
21
|
+
* because ${} values are sent as bound parameters, not string-concatenated.
|
|
22
|
+
*
|
|
23
|
+
* - postgres / postgresjs: sql`SELECT * FROM users WHERE id = ${id}`
|
|
24
|
+
* - slonik: sql.unsafe`...` (raw) vs sql`...` (parameterized)
|
|
25
|
+
* - @electric-sql/pglite: tagged template syntax
|
|
26
|
+
* - sql-template-strings / sql-template-tag: tagged template helpers
|
|
27
|
+
*/
|
|
28
|
+
const TAGGED_TEMPLATE_SQL_LIBS = [
|
|
29
|
+
/from\s+['"]postgres['"]/, // import postgres from 'postgres'
|
|
30
|
+
/require\s*\(\s*['"]postgres['"]\s*\)/, // const sql = require('postgres')
|
|
31
|
+
/from\s+['"]slonik['"]/,
|
|
32
|
+
/from\s+['"]@electric-sql\/pglite['"]/,
|
|
33
|
+
/from\s+['"]sql-template-strings['"]/,
|
|
34
|
+
/from\s+['"]sql-template-tag['"]/,
|
|
35
|
+
/postgres\.Sql\b/, // type annotation: db: postgres.Sql
|
|
36
|
+
/:\s*Sql\b/, // short form: db: Sql (with import type { Sql } from 'postgres')
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Returns all hand-crafted formal checks as StreamingCheck objects.
|
|
40
|
+
*
|
|
41
|
+
* These cover the key vulnerability patterns from formal-verifier.ts,
|
|
42
|
+
* adapted for streaming (line/statement-level) detection during generation.
|
|
43
|
+
*/
|
|
44
|
+
export function getFormalChecks() {
|
|
45
|
+
return FORMAL_CHECKS;
|
|
46
|
+
}
|
|
47
|
+
const FORMAL_CHECKS = [
|
|
48
|
+
// 1. SQL injection — string concatenation in queries
|
|
49
|
+
{
|
|
50
|
+
id: 'sql_concat_injection',
|
|
51
|
+
name: 'SQL string concatenation',
|
|
52
|
+
languages: [...JS_LANGS, ...PY_LANGS],
|
|
53
|
+
pattern: /(?:SELECT|INSERT|UPDATE|DELETE)\s[^;]*["'`]\s*\+\s*\w+/i,
|
|
54
|
+
verdict: 'FAIL',
|
|
55
|
+
severity: 'critical',
|
|
56
|
+
evidenceTemplate: 'SQL query uses string concatenation: $0',
|
|
57
|
+
suggestion: 'Use parameterized queries ($1, ?, or :named placeholders) instead of string concatenation.',
|
|
58
|
+
source: 'formal',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'sql_template_injection',
|
|
62
|
+
name: 'SQL template literal injection',
|
|
63
|
+
languages: JS_LANGS,
|
|
64
|
+
pattern: /`[^`]*(?:SELECT|INSERT|UPDATE|DELETE)[^`]*\$\{(?!\d)/i,
|
|
65
|
+
verdict: 'FAIL',
|
|
66
|
+
severity: 'critical',
|
|
67
|
+
evidenceTemplate: 'SQL query uses template literal interpolation: $0',
|
|
68
|
+
suggestion: 'Use parameterized queries instead of template literal interpolation in SQL strings.',
|
|
69
|
+
source: 'formal',
|
|
70
|
+
// Suppressed when file uses tagged template libraries (postgres.js, slonik, pglite, sql-template-strings)
|
|
71
|
+
// These libraries use tagged template literals as their parameterization mechanism — ${} values
|
|
72
|
+
// are sent as bound parameters, not concatenated into SQL strings.
|
|
73
|
+
suppressWhen: TAGGED_TEMPLATE_SQL_LIBS,
|
|
74
|
+
},
|
|
75
|
+
// 2. Missing error handling — unhandled promise chains
|
|
76
|
+
{
|
|
77
|
+
id: 'unhandled_promise',
|
|
78
|
+
name: 'Unhandled promise (no .catch)',
|
|
79
|
+
languages: JS_LANGS,
|
|
80
|
+
pattern: /(?:fetch|axios\.\w+)\s*\([^)]*\)\s*\.then\s*\([^)]*\)(?![\s\S]*\.catch)/,
|
|
81
|
+
verdict: 'FAIL',
|
|
82
|
+
severity: 'high',
|
|
83
|
+
evidenceTemplate: 'Promise chain without .catch() handler: $0',
|
|
84
|
+
suggestion: 'Add a .catch() handler or use try/catch with await.',
|
|
85
|
+
source: 'formal',
|
|
86
|
+
},
|
|
87
|
+
// 3. Hardcoded credentials/secrets
|
|
88
|
+
{
|
|
89
|
+
id: 'hardcoded_secret',
|
|
90
|
+
name: 'Hardcoded secret or API key',
|
|
91
|
+
languages: ALL_LANGS,
|
|
92
|
+
pattern: /(?:const|let|var|=)\s*(?:\w+)?\s*(?:api[_-]?key|secret|password|token|auth)\s*=\s*["'`](?:sk-|pk-|ghp_|gho_|github_pat_|xox[bpors]-|AIza|AKIA|bearer\s).{8,}/i,
|
|
93
|
+
verdict: 'FAIL',
|
|
94
|
+
severity: 'critical',
|
|
95
|
+
evidenceTemplate: 'Hardcoded secret detected: $0',
|
|
96
|
+
suggestion: 'Use environment variables or a secrets manager instead of hardcoding credentials.',
|
|
97
|
+
source: 'formal',
|
|
98
|
+
},
|
|
99
|
+
// 4. Unsafe eval / Function constructor
|
|
100
|
+
{
|
|
101
|
+
id: 'unsafe_eval',
|
|
102
|
+
name: 'Unsafe eval() usage',
|
|
103
|
+
languages: JS_LANGS,
|
|
104
|
+
pattern: /\beval\s*\(\s*(?!\s*['"`][\s\S]*['"`]\s*\))/, // eval( but not eval("literal")
|
|
105
|
+
verdict: 'FAIL',
|
|
106
|
+
severity: 'critical',
|
|
107
|
+
evidenceTemplate: 'Unsafe eval() call detected: $0',
|
|
108
|
+
suggestion: 'Replace eval() with a safer alternative like JSON.parse() or a sandboxed evaluator.',
|
|
109
|
+
source: 'formal',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'unsafe_function_constructor',
|
|
113
|
+
name: 'Unsafe Function constructor',
|
|
114
|
+
languages: JS_LANGS,
|
|
115
|
+
pattern: /new\s+Function\s*\(/,
|
|
116
|
+
verdict: 'FAIL',
|
|
117
|
+
severity: 'critical',
|
|
118
|
+
evidenceTemplate: 'Unsafe new Function() call detected: $0',
|
|
119
|
+
suggestion: 'Avoid new Function(). Use static code paths or a sandboxed evaluator.',
|
|
120
|
+
source: 'formal',
|
|
121
|
+
},
|
|
122
|
+
// 5. Insecure randomness (Math.random for security)
|
|
123
|
+
{
|
|
124
|
+
id: 'insecure_random',
|
|
125
|
+
name: 'Math.random() used for security',
|
|
126
|
+
languages: JS_LANGS,
|
|
127
|
+
pattern: /(?:token|secret|key|nonce|csrf|session|password|salt|hash)\s*(?:=|:)\s*.*Math\.random/i,
|
|
128
|
+
verdict: 'FAIL',
|
|
129
|
+
severity: 'high',
|
|
130
|
+
evidenceTemplate: 'Math.random() used in security-sensitive context: $0',
|
|
131
|
+
suggestion: 'Use crypto.randomUUID() or crypto.getRandomValues() for security-sensitive random values.',
|
|
132
|
+
source: 'formal',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'insecure_random_token',
|
|
136
|
+
name: 'Math.random() token generation',
|
|
137
|
+
languages: JS_LANGS,
|
|
138
|
+
pattern: /Math\.random\(\)\.toString\(36\)/,
|
|
139
|
+
verdict: 'FAIL',
|
|
140
|
+
severity: 'high',
|
|
141
|
+
evidenceTemplate: 'Insecure token generation using Math.random(): $0',
|
|
142
|
+
suggestion: 'Use crypto.randomUUID() or crypto.randomBytes() for token generation.',
|
|
143
|
+
source: 'formal',
|
|
144
|
+
},
|
|
145
|
+
// 6. Prototype pollution patterns
|
|
146
|
+
{
|
|
147
|
+
id: 'prototype_pollution',
|
|
148
|
+
name: 'Prototype pollution risk',
|
|
149
|
+
languages: JS_LANGS,
|
|
150
|
+
pattern: /\w+\[(?:\w+|\w+\[\w+\])\]\s*=\s*(?!\s*(?:null|undefined|false|true|0|''|""|``)\s*[;,)])/,
|
|
151
|
+
verdict: 'FAIL',
|
|
152
|
+
severity: 'high',
|
|
153
|
+
evidenceTemplate: 'Dynamic property assignment may allow prototype pollution: $0',
|
|
154
|
+
suggestion: 'Validate property names against __proto__, constructor, and prototype before dynamic assignment.',
|
|
155
|
+
source: 'formal',
|
|
156
|
+
},
|
|
157
|
+
// 7. Path traversal
|
|
158
|
+
{
|
|
159
|
+
id: 'path_traversal',
|
|
160
|
+
name: 'Path traversal vulnerability',
|
|
161
|
+
languages: [...JS_LANGS, ...PY_LANGS],
|
|
162
|
+
pattern: /(?:readFile|readFileSync|createReadStream|writeFile|writeFileSync|open)\s*\(\s*(?:req\.(?:params|query|body)|request\.(?:args|form|json))\s*[\[.]/,
|
|
163
|
+
verdict: 'FAIL',
|
|
164
|
+
severity: 'critical',
|
|
165
|
+
evidenceTemplate: 'User input passed directly to filesystem operation: $0',
|
|
166
|
+
suggestion: 'Sanitize file paths with path.resolve() and verify they stay within the intended directory.',
|
|
167
|
+
source: 'formal',
|
|
168
|
+
},
|
|
169
|
+
// 8. Command injection
|
|
170
|
+
{
|
|
171
|
+
id: 'command_injection',
|
|
172
|
+
name: 'Command injection vulnerability',
|
|
173
|
+
languages: [...JS_LANGS, ...PY_LANGS],
|
|
174
|
+
pattern: /(?:exec|execSync|spawn|spawnSync|system|popen)\s*\(\s*(?:["'`][^"'`]*["'`]\s*\+|`[^`]*\$\{)/,
|
|
175
|
+
verdict: 'FAIL',
|
|
176
|
+
severity: 'critical',
|
|
177
|
+
evidenceTemplate: 'Command injection risk — shell command built with concatenation: $0',
|
|
178
|
+
suggestion: 'Use execFile() or spawn() with an argument array instead of exec() with string concatenation.',
|
|
179
|
+
source: 'formal',
|
|
180
|
+
},
|
|
181
|
+
// 9. Null/undefined access without check
|
|
182
|
+
{
|
|
183
|
+
id: 'unchecked_array_index',
|
|
184
|
+
name: 'Unchecked array index access',
|
|
185
|
+
languages: JS_LANGS,
|
|
186
|
+
pattern: /\w+\[0\]\.\w+(?!\s*\?\.)/, // arr[0].prop without optional chaining
|
|
187
|
+
verdict: 'FAIL',
|
|
188
|
+
severity: 'medium',
|
|
189
|
+
evidenceTemplate: 'Array element accessed without null check: $0',
|
|
190
|
+
suggestion: 'Check array length before accessing elements, or use optional chaining (arr[0]?.prop).',
|
|
191
|
+
source: 'formal',
|
|
192
|
+
},
|
|
193
|
+
// 10. Input validation missing — direct use of request params in DB queries
|
|
194
|
+
{
|
|
195
|
+
id: 'unvalidated_input_to_query',
|
|
196
|
+
name: 'Unvalidated input passed to database query',
|
|
197
|
+
languages: JS_LANGS,
|
|
198
|
+
pattern: /\.(?:query|execute|findOne|find|delete|update)\s*\(\s*\{[^}]*(?:req\.(?:params|query|body)|request\.\w+)/,
|
|
199
|
+
verdict: 'FAIL',
|
|
200
|
+
severity: 'high',
|
|
201
|
+
evidenceTemplate: 'Request input passed directly to database query without validation: $0',
|
|
202
|
+
suggestion: 'Validate and sanitize request input with zod, joi, or manual type checks before passing to queries.',
|
|
203
|
+
source: 'formal',
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
// ── Learned Rule Conversion ─────────────────────────────────────
|
|
207
|
+
/**
|
|
208
|
+
* Keyword map: maps keyword triggers found in rule name/description/category
|
|
209
|
+
* to context keywords that must appear in code for the rule to be relevant.
|
|
210
|
+
*
|
|
211
|
+
* When a rule's name, description, or category contains a trigger (left side),
|
|
212
|
+
* the associated keywords (right side) are assigned. The check only runs if
|
|
213
|
+
* at least one keyword is found in the code unit text.
|
|
214
|
+
*/
|
|
215
|
+
const CONTEXT_KEYWORD_MAP = [
|
|
216
|
+
// React / JSX
|
|
217
|
+
{
|
|
218
|
+
triggers: /\b(?:react|jsx|tsx|component|hook|use[A-Z]\w+|memo(?:iz)|useEffect|useState|useRef|useCallback|useMemo)\b/i,
|
|
219
|
+
keywords: ['React', 'useState', 'useEffect', 'useRef', 'useCallback', 'useMemo', 'jsx', 'tsx', 'import react', 'from \'react', 'from "react'],
|
|
220
|
+
},
|
|
221
|
+
// OpenAPI / Swagger / NestJS decorators
|
|
222
|
+
{
|
|
223
|
+
triggers: /\b(?:openapi|swagger|@Api\w*|@Controller|@Get|@Post|@Put|@Delete|@Patch|decorator|NestJS)\b/i,
|
|
224
|
+
keywords: ['@Api', '@Controller', '@Get(', '@Post(', '@Put(', '@Delete(', '@Patch(', 'swagger', 'openapi', '@nestjs'],
|
|
225
|
+
},
|
|
226
|
+
// Canvas / Drawing / 2D rendering
|
|
227
|
+
{
|
|
228
|
+
triggers: /\b(?:canvas|drawImage|getContext|2d\s*context|fillRect|strokeRect|beginPath|WebGL)\b/i,
|
|
229
|
+
keywords: ['canvas', 'drawImage', 'getContext', 'fillRect', 'strokeRect', 'beginPath', 'CanvasRenderingContext', 'webgl'],
|
|
230
|
+
},
|
|
231
|
+
// Stripe
|
|
232
|
+
{
|
|
233
|
+
triggers: /\b(?:stripe|payment.?intent|checkout.?session|subscription)\b/i,
|
|
234
|
+
keywords: ['stripe', 'Stripe', 'payment_intent', 'checkout.sessions', 'PaymentIntent'],
|
|
235
|
+
},
|
|
236
|
+
// GraphQL
|
|
237
|
+
{
|
|
238
|
+
triggers: /\b(?:graphql|resolver|mutation|gql`|@Query|@Mutation|@Resolver)\b/i,
|
|
239
|
+
keywords: ['graphql', 'GraphQL', 'gql`', '@Query', '@Mutation', '@Resolver', 'typeDefs', 'resolvers'],
|
|
240
|
+
},
|
|
241
|
+
// Docker / Container
|
|
242
|
+
{
|
|
243
|
+
triggers: /\b(?:docker|dockerfile|container|ENTRYPOINT|CMD\s)\b/i,
|
|
244
|
+
keywords: ['FROM ', 'ENTRYPOINT', 'CMD [', 'EXPOSE ', 'Dockerfile', 'docker-compose'],
|
|
245
|
+
},
|
|
246
|
+
// Redis
|
|
247
|
+
{
|
|
248
|
+
triggers: /\b(?:redis|HSET|HGET|ZADD|pub.?sub|ioredis)\b/i,
|
|
249
|
+
keywords: ['redis', 'Redis', 'ioredis', 'HSET', 'HGET', 'createClient'],
|
|
250
|
+
},
|
|
251
|
+
// MongoDB / Mongoose
|
|
252
|
+
{
|
|
253
|
+
triggers: /\b(?:mongo(?:db|ose)?|Schema\.Types|ObjectId|aggregate)\b/i,
|
|
254
|
+
keywords: ['mongoose', 'MongoDB', 'MongoClient', 'Schema.Types', 'ObjectId', '.aggregate('],
|
|
255
|
+
},
|
|
256
|
+
// Django
|
|
257
|
+
{
|
|
258
|
+
triggers: /\b(?:django|models\.Model|views\.py|urls\.py|INSTALLED_APPS)\b/i,
|
|
259
|
+
keywords: ['django', 'Django', 'models.Model', 'INSTALLED_APPS', 'urlpatterns', 'from django'],
|
|
260
|
+
},
|
|
261
|
+
// Flask
|
|
262
|
+
{
|
|
263
|
+
triggers: /\b(?:flask|@app\.route|Blueprint|Jinja)\b/i,
|
|
264
|
+
keywords: ['flask', 'Flask', '@app.route', 'Blueprint', 'from flask'],
|
|
265
|
+
},
|
|
266
|
+
// Vue
|
|
267
|
+
{
|
|
268
|
+
triggers: /\b(?:vue|v-model|v-bind|v-if|defineComponent|ref\(\)|computed\(\))\b/i,
|
|
269
|
+
keywords: ['vue', 'Vue', 'v-model', 'v-bind', 'defineComponent', 'from \'vue', 'from "vue'],
|
|
270
|
+
},
|
|
271
|
+
// Angular
|
|
272
|
+
{
|
|
273
|
+
triggers: /\b(?:angular|@Component|@Injectable|@NgModule|ngOnInit)\b/i,
|
|
274
|
+
keywords: ['@Component', '@Injectable', '@NgModule', 'ngOnInit', '@angular', 'from \'@angular'],
|
|
275
|
+
},
|
|
276
|
+
// WebSocket
|
|
277
|
+
{
|
|
278
|
+
triggers: /\b(?:websocket|ws:\/\/|wss:\/\/|socket\.io|onmessage)\b/i,
|
|
279
|
+
keywords: ['WebSocket', 'ws://', 'wss://', 'socket.io', 'onmessage', 'Socket('],
|
|
280
|
+
},
|
|
281
|
+
// AWS SDK
|
|
282
|
+
{
|
|
283
|
+
triggers: /\b(?:aws.?sdk|S3Client|DynamoDB|Lambda|SQS|SNS|@aws-sdk)\b/i,
|
|
284
|
+
keywords: ['aws-sdk', '@aws-sdk', 'S3Client', 'DynamoDB', 'LambdaClient', 'SQSClient'],
|
|
285
|
+
},
|
|
286
|
+
// Prisma
|
|
287
|
+
{
|
|
288
|
+
triggers: /\b(?:prisma|PrismaClient|prisma\.\$|findUnique|findMany)\b/i,
|
|
289
|
+
keywords: ['prisma', 'Prisma', 'PrismaClient', 'prisma.', '@prisma/client'],
|
|
290
|
+
},
|
|
291
|
+
];
|
|
292
|
+
/**
|
|
293
|
+
* Derive context keywords for a learned rule based on its name, description,
|
|
294
|
+
* and category. Returns undefined if no specific context can be inferred
|
|
295
|
+
* (the rule will run against all code units).
|
|
296
|
+
*/
|
|
297
|
+
function deriveContextKeywords(rule) {
|
|
298
|
+
const searchText = [
|
|
299
|
+
rule.pattern.description,
|
|
300
|
+
rule.pattern.claimCategory,
|
|
301
|
+
rule.id,
|
|
302
|
+
rule.fixDescription ?? '',
|
|
303
|
+
].join(' ');
|
|
304
|
+
for (const entry of CONTEXT_KEYWORD_MAP) {
|
|
305
|
+
if (entry.triggers.test(searchText)) {
|
|
306
|
+
return entry.keywords;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Fallback: try to extract literal strings from the regex pattern itself.
|
|
310
|
+
// Sequences of 4+ alphanumeric chars (likely meaningful identifiers).
|
|
311
|
+
if (rule.pattern.regexPattern) {
|
|
312
|
+
const literals = extractRegexLiterals(rule.pattern.regexPattern);
|
|
313
|
+
if (literals.length > 0) {
|
|
314
|
+
return literals;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Extract literal substrings (4+ alphanumeric chars) from a regex pattern.
|
|
321
|
+
* These are likely the actual identifiers the rule is looking for.
|
|
322
|
+
*/
|
|
323
|
+
function extractRegexLiterals(regexStr) {
|
|
324
|
+
// Match sequences of word chars that are at least 4 chars long,
|
|
325
|
+
// excluding common regex syntax fragments
|
|
326
|
+
const REGEX_NOISE = new Set([
|
|
327
|
+
'true', 'false', 'null', 'undefined', 'this', 'that',
|
|
328
|
+
'with', 'from', 'each', 'some', 'every', 'filter',
|
|
329
|
+
]);
|
|
330
|
+
const matches = regexStr.match(/[a-zA-Z_][a-zA-Z0-9_]{3,}/g) ?? [];
|
|
331
|
+
const unique = [...new Set(matches)].filter(m => !REGEX_NOISE.has(m.toLowerCase()));
|
|
332
|
+
return unique.length <= 10 ? unique : unique.slice(0, 10);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Load learned rules from the catalog and convert them to StreamingCheck format.
|
|
336
|
+
*
|
|
337
|
+
* Default path: `.assay/learned/rules.json` relative to process.cwd().
|
|
338
|
+
* Falls back to an empty set if the file doesn't exist (starter rules
|
|
339
|
+
* are loaded separately by getFormalChecks equivalent in the catalog).
|
|
340
|
+
*
|
|
341
|
+
* Each rule is assigned contextKeywords for relevance filtering — the check
|
|
342
|
+
* only runs on code units that contain at least one keyword.
|
|
343
|
+
*/
|
|
344
|
+
export function loadLearnedChecks(catalogPath) {
|
|
345
|
+
const filePath = catalogPath ?? join(process.cwd(), '.assay', 'learned', 'rules.json');
|
|
346
|
+
let rules;
|
|
347
|
+
try {
|
|
348
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
349
|
+
const parsed = JSON.parse(content);
|
|
350
|
+
rules = Array.isArray(parsed) ? parsed : [];
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// No catalog on disk — return empty (starter rules are part of formal checks)
|
|
354
|
+
return [];
|
|
355
|
+
}
|
|
356
|
+
return rules
|
|
357
|
+
.filter(r => r.status === 'promoted' || r.status === 'validated')
|
|
358
|
+
.filter(r => r.pattern.kind === 'regex' && r.pattern.regexPattern)
|
|
359
|
+
.map(r => learnedRuleToCheck(r));
|
|
360
|
+
}
|
|
361
|
+
function learnedRuleToCheck(rule) {
|
|
362
|
+
let pattern;
|
|
363
|
+
try {
|
|
364
|
+
pattern = new RegExp(rule.pattern.regexPattern, 'i');
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
// Invalid regex — create a pattern that never matches
|
|
368
|
+
pattern = /(?!)/;
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
id: `learned_${rule.id}`,
|
|
372
|
+
name: rule.pattern.description.slice(0, 80),
|
|
373
|
+
languages: [...rule.pattern.languages],
|
|
374
|
+
pattern,
|
|
375
|
+
verdict: rule.pattern.matchBehavior === 'presence_is_bad' ? 'FAIL' : 'PASS',
|
|
376
|
+
severity: rule.pattern.severity,
|
|
377
|
+
evidenceTemplate: rule.pattern.evidenceTemplate,
|
|
378
|
+
suggestion: rule.fixDescription,
|
|
379
|
+
source: 'learned',
|
|
380
|
+
contextKeywords: deriveContextKeywords(rule),
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
// Exported for testing
|
|
384
|
+
export { deriveContextKeywords as _deriveContextKeywords, extractRegexLiterals as _extractRegexLiterals };
|
|
385
|
+
// ── Compilation ─────────────────────────────────────────────────
|
|
386
|
+
/**
|
|
387
|
+
* Filter checks by language and return a pre-compiled set ready for fast execution.
|
|
388
|
+
*
|
|
389
|
+
* If no checks are provided, uses the built-in formal checks.
|
|
390
|
+
*/
|
|
391
|
+
export function compileCheckSet(language, checks) {
|
|
392
|
+
const start = performance.now();
|
|
393
|
+
const allChecks = checks ?? FORMAL_CHECKS;
|
|
394
|
+
const langLower = language.toLowerCase();
|
|
395
|
+
const filtered = allChecks.filter(check => {
|
|
396
|
+
if (check.languages.length === 0)
|
|
397
|
+
return true; // applies to all languages
|
|
398
|
+
return check.languages.some(l => l.toLowerCase() === langLower);
|
|
399
|
+
});
|
|
400
|
+
const compileTimeMs = performance.now() - start;
|
|
401
|
+
return {
|
|
402
|
+
checks: filtered,
|
|
403
|
+
language: langLower,
|
|
404
|
+
compileTimeMs,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
// ── Execution ───────────────────────────────────────────────────
|
|
408
|
+
/**
|
|
409
|
+
* Run all checks in the set against a code unit. Returns verification events.
|
|
410
|
+
*
|
|
411
|
+
* Designed to complete in <10ms for the full check set against a typical code unit.
|
|
412
|
+
*/
|
|
413
|
+
export function runChecks(unit, checkSet) {
|
|
414
|
+
const events = [];
|
|
415
|
+
const unitStart = performance.now();
|
|
416
|
+
const textLower = unit.text.toLowerCase();
|
|
417
|
+
for (const check of checkSet.checks) {
|
|
418
|
+
// Level 2 filtering: skip checks whose contextKeywords don't match the code
|
|
419
|
+
if (check.contextKeywords && check.contextKeywords.length > 0) {
|
|
420
|
+
const hasRelevantKeyword = check.contextKeywords.some(kw => textLower.includes(kw.toLowerCase()));
|
|
421
|
+
if (!hasRelevantKeyword)
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const checkStart = performance.now();
|
|
425
|
+
// Suppression: skip check if any suppressWhen pattern matches the code
|
|
426
|
+
if (check.suppressWhen && check.suppressWhen.some(re => re.test(unit.text))) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
// Reset lastIndex for patterns with the global flag
|
|
430
|
+
check.pattern.lastIndex = 0;
|
|
431
|
+
const match = check.pattern.exec(unit.text);
|
|
432
|
+
const latencyMs = performance.now() - checkStart;
|
|
433
|
+
if (match && check.verdict === 'FAIL') {
|
|
434
|
+
// Pattern matched and that means a failure
|
|
435
|
+
const evidence = formatEvidence(check.evidenceTemplate, match);
|
|
436
|
+
events.push({
|
|
437
|
+
type: 'finding',
|
|
438
|
+
codeUnit: unit,
|
|
439
|
+
checkId: check.id,
|
|
440
|
+
checkName: check.name,
|
|
441
|
+
verdict: 'FAIL',
|
|
442
|
+
evidence,
|
|
443
|
+
severity: check.severity,
|
|
444
|
+
suggestion: check.suggestion,
|
|
445
|
+
latencyMs,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
else if (!match && check.verdict === 'PASS') {
|
|
449
|
+
// Pattern was supposed to match (PASS means "match = good") but didn't
|
|
450
|
+
// This is the absence_is_bad case from learned rules
|
|
451
|
+
events.push({
|
|
452
|
+
type: 'finding',
|
|
453
|
+
codeUnit: unit,
|
|
454
|
+
checkId: check.id,
|
|
455
|
+
checkName: check.name,
|
|
456
|
+
verdict: 'FAIL',
|
|
457
|
+
evidence: formatEvidence(check.evidenceTemplate, null),
|
|
458
|
+
severity: check.severity,
|
|
459
|
+
suggestion: check.suggestion,
|
|
460
|
+
latencyMs,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
// Other cases: match+PASS (good) or no-match+FAIL (no problem found) — no event
|
|
464
|
+
}
|
|
465
|
+
return events;
|
|
466
|
+
}
|
|
467
|
+
// ── Helpers ─────────────────────────────────────────────────────
|
|
468
|
+
function formatEvidence(template, match) {
|
|
469
|
+
if (!match)
|
|
470
|
+
return template;
|
|
471
|
+
let result = template;
|
|
472
|
+
// Replace $0 with full match
|
|
473
|
+
result = result.replace(/\$0/g, match[0]);
|
|
474
|
+
// Replace $1, $2, etc. with capture groups
|
|
475
|
+
for (let i = 1; i < match.length; i++) {
|
|
476
|
+
result = result.replace(new RegExp(`\\$${i}`, 'g'), match[i] ?? '');
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
//# sourceMappingURL=streaming-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-checks.js","sourceRoot":"","sources":["../../src/realtime/streaming-checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAUjC,mEAAmE;AAEnE,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACxE,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAClC,MAAM,SAAS,GAAa,EAAE,CAAC,CAAC,yBAAyB;AAEzD;;;;;;;;;GASG;AACH,MAAM,wBAAwB,GAAa;IACzC,yBAAyB,EAAc,kCAAkC;IACzE,sCAAsC,EAAE,kCAAkC;IAC1E,uBAAuB;IACvB,sCAAsC;IACtC,qCAAqC;IACrC,iCAAiC;IACjC,iBAAiB,EAAuB,oCAAoC;IAC5E,WAAW,EAA6B,iEAAiE;CAC1G,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,aAAa,GAAqB;IACtC,qDAAqD;IACrD;QACE,EAAE,EAAE,sBAAsB;QAC1B,IAAI,EAAE,0BAA0B;QAChC,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,EAAE,yDAAyD;QAClE,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,yCAAyC;QAC3D,UAAU,EAAE,4FAA4F;QACxG,MAAM,EAAE,QAAQ;KACjB;IACD;QACE,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,gCAAgC;QACtC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,uDAAuD;QAChE,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,mDAAmD;QACrE,UAAU,EAAE,qFAAqF;QACjG,MAAM,EAAE,QAAQ;QAChB,0GAA0G;QAC1G,gGAAgG;QAChG,mEAAmE;QACnE,YAAY,EAAE,wBAAwB;KACvC;IAED,uDAAuD;IACvD;QACE,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,+BAA+B;QACrC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,yEAAyE;QAClF,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,4CAA4C;QAC9D,UAAU,EAAE,qDAAqD;QACjE,MAAM,EAAE,QAAQ;KACjB;IAED,mCAAmC;IACnC;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,6BAA6B;QACnC,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,+JAA+J;QACxK,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,+BAA+B;QACjD,UAAU,EAAE,mFAAmF;QAC/F,MAAM,EAAE,QAAQ;KACjB;IAED,wCAAwC;IACxC;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,qBAAqB;QAC3B,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,6CAA6C,EAAE,gCAAgC;QACxF,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,iCAAiC;QACnD,UAAU,EAAE,qFAAqF;QACjG,MAAM,EAAE,QAAQ;KACjB;IACD;QACE,EAAE,EAAE,6BAA6B;QACjC,IAAI,EAAE,6BAA6B;QACnC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,yCAAyC;QAC3D,UAAU,EAAE,uEAAuE;QACnF,MAAM,EAAE,QAAQ;KACjB;IAED,oDAAoD;IACpD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,iCAAiC;QACvC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,wFAAwF;QACjG,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,sDAAsD;QACxE,UAAU,EAAE,2FAA2F;QACvG,MAAM,EAAE,QAAQ;KACjB;IACD;QACE,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,gCAAgC;QACtC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,kCAAkC;QAC3C,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,mDAAmD;QACrE,UAAU,EAAE,uEAAuE;QACnF,MAAM,EAAE,QAAQ;KACjB;IAED,kCAAkC;IAClC;QACE,EAAE,EAAE,qBAAqB;QACzB,IAAI,EAAE,0BAA0B;QAChC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,yFAAyF;QAClG,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,+DAA+D;QACjF,UAAU,EAAE,kGAAkG;QAC9G,MAAM,EAAE,QAAQ;KACjB;IAED,oBAAoB;IACpB;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,8BAA8B;QACpC,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,EAAE,mJAAmJ;QAC5J,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,wDAAwD;QAC1E,UAAU,EAAE,6FAA6F;QACzG,MAAM,EAAE,QAAQ;KACjB;IAED,uBAAuB;IACvB;QACE,EAAE,EAAE,mBAAmB;QACvB,IAAI,EAAE,iCAAiC;QACvC,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,EAAE,6FAA6F;QACtG,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,qEAAqE;QACvF,UAAU,EAAE,+FAA+F;QAC3G,MAAM,EAAE,QAAQ;KACjB;IAED,yCAAyC;IACzC;QACE,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,8BAA8B;QACpC,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,0BAA0B,EAAE,wCAAwC;QAC7E,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,QAAQ;QAClB,gBAAgB,EAAE,+CAA+C;QACjE,UAAU,EAAE,wFAAwF;QACpG,MAAM,EAAE,QAAQ;KACjB;IAED,4EAA4E;IAC5E;QACE,EAAE,EAAE,4BAA4B;QAChC,IAAI,EAAE,4CAA4C;QAClD,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,0GAA0G;QACnH,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,MAAM;QAChB,gBAAgB,EAAE,wEAAwE;QAC1F,UAAU,EAAE,qGAAqG;QACjH,MAAM,EAAE,QAAQ;KACjB;CACF,CAAC;AAEF,mEAAmE;AAEnE;;;;;;;GAOG;AACH,MAAM,mBAAmB,GAAoD;IAC3E,cAAc;IACd;QACE,QAAQ,EAAE,4GAA4G;QACtH,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC;KAC9I;IACD,wCAAwC;IACxC;QACE,QAAQ,EAAE,8FAA8F;QACxG,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;KACtH;IACD,kCAAkC;IAClC;QACE,QAAQ,EAAE,uFAAuF;QACjG,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,OAAO,CAAC;KAC1H;IACD,SAAS;IACT;QACE,QAAQ,EAAE,gEAAgE;QAC1E,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,eAAe,CAAC;KACvF;IACD,UAAU;IACV;QACE,QAAQ,EAAE,oEAAoE;QAC9E,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC;KACtG;IACD,qBAAqB;IACrB;QACE,QAAQ,EAAE,uDAAuD;QACjE,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,CAAC;KACtF;IACD,QAAQ;IACR;QACE,QAAQ,EAAE,gDAAgD;QAC1D,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC;KACxE;IACD,qBAAqB;IACrB;QACE,QAAQ,EAAE,4DAA4D;QACtE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,CAAC;KAC5F;IACD,SAAS;IACT;QACE,QAAQ,EAAE,iEAAiE;QAC3E,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,CAAC;KAC/F;IACD,QAAQ;IACR;QACE,QAAQ,EAAE,4CAA4C;QACtD,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC;KACtE;IACD,MAAM;IACN;QACE,QAAQ,EAAE,uEAAuE;QACjF,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,CAAC;KAC5F;IACD,UAAU;IACV;QACE,QAAQ,EAAE,4DAA4D;QACtE,QAAQ,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,CAAC;KAChG;IACD,YAAY;IACZ;QACE,QAAQ,EAAE,0DAA0D;QACpE,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,CAAC;KAChF;IACD,UAAU;IACV;QACE,QAAQ,EAAE,6DAA6D;QACvE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,CAAC;KACvF;IACD,SAAS;IACT;QACE,QAAQ,EAAE,6DAA6D;QACvE,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,CAAC;KAC5E;CACF,CAAC;AAEF;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,IAAiB;IAC9C,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,OAAO,CAAC,WAAW;QACxB,IAAI,CAAC,OAAO,CAAC,aAAa;QAC1B,IAAI,CAAC,EAAE;QACP,IAAI,CAAC,cAAc,IAAI,EAAE;KAC1B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,KAAK,IAAI,mBAAmB,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC,QAAQ,CAAC;QACxB,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,sEAAsE;IACtE,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,gEAAgE;IAChE,0CAA0C;IAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;QAC1B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM;QACpD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ;KAClD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,CAAC;IACnE,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACpF,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAoB;IACpD,MAAM,QAAQ,GAAG,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAEvF,IAAI,KAAoB,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;QAC9E,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC;SAChE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;SACjE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAiB;IAC3C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAa,EAAE,GAAG,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;QACtD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IAED,OAAO;QACL,EAAE,EAAE,WAAW,IAAI,CAAC,EAAE,EAAE;QACxB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3C,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QACtC,OAAO;QACP,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAC3E,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAyB;QAChD,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;QAC/C,UAAU,EAAE,IAAI,CAAC,cAAc;QAC/B,MAAM,EAAE,SAAS;QACjB,eAAe,EAAE,qBAAqB,CAAC,IAAI,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,uBAAuB;AACvB,OAAO,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,CAAC;AAE1G,mEAAmE;AAEnE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,MAAyB;IAEzB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,IAAI,aAAa,CAAC;IAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAEzC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACxC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,2BAA2B;QAC1E,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAEhD,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,SAAS;QACnB,aAAa;KACd,CAAC;AACJ,CAAC;AAED,mEAAmE;AAEnE;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,IAAc,EACd,QAA0B;IAE1B,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAE1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,4EAA4E;QAC5E,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9D,MAAM,kBAAkB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CACnD,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAC3C,CAAC;YACF,IAAI,CAAC,kBAAkB;gBAAE,SAAS;QACpC,CAAC;QAED,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAErC,uEAAuE;QACvE,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC5E,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC;QAEjD,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;YACtC,2CAA2C;YAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;YAC/D,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO,EAAE,MAAM;gBACf,QAAQ;gBACR,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,SAAS;aACV,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;YAC9C,uEAAuE;YACvE,qDAAqD;YACrD,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC;gBACtD,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QACD,gFAAgF;IAClF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mEAAmE;AAEnE,SAAS,cAAc,CAAC,QAAgB,EAAE,KAA6B;IACrE,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAE5B,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,6BAA6B;IAC7B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,2CAA2C;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamingVerifier — orchestrator for the real-time verification pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Wires CodeBuffer (token accumulation + code unit detection) with
|
|
5
|
+
* StreamingChecks (pattern-based formal + learned checks) into a single
|
|
6
|
+
* stateful pipeline. Feed it tokens, it buffers them, detects completed
|
|
7
|
+
* code units, runs checks, and emits verification events.
|
|
8
|
+
*/
|
|
9
|
+
import type { CheckSeverity, StreamingVerifierStats, VerificationEvent } from './types.js';
|
|
10
|
+
import type { EntropyDetector } from './entropy-detector.js';
|
|
11
|
+
export interface StreamingVerifierOptions {
|
|
12
|
+
language: string;
|
|
13
|
+
/** Path to project root for loading learned rules catalog */
|
|
14
|
+
projectPath?: string;
|
|
15
|
+
/** Callback fired for each verification event */
|
|
16
|
+
onEvent?: (event: VerificationEvent) => void;
|
|
17
|
+
/** Only auto-correct findings at or above this severity. Default: 'high' */
|
|
18
|
+
minCorrectionSeverity?: CheckSeverity;
|
|
19
|
+
/**
|
|
20
|
+
* Enable adaptive verification depth based on BAS score.
|
|
21
|
+
* When true:
|
|
22
|
+
* - green (BAS < 0.3): skip formal checks for this block
|
|
23
|
+
* - amber (BAS 0.3–0.7): queue formal checks for async execution
|
|
24
|
+
* - red (BAS > 0.7): run formal checks immediately
|
|
25
|
+
* When false (default): run all checks on every block (current behavior).
|
|
26
|
+
*/
|
|
27
|
+
adaptiveDepth?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Optional entropy detector instance. When provided and adaptiveDepth is
|
|
30
|
+
* true, the verifier consumes BAS depth from the detector to route checks.
|
|
31
|
+
*/
|
|
32
|
+
entropyDetector?: EntropyDetector;
|
|
33
|
+
}
|
|
34
|
+
export declare class StreamingVerifier {
|
|
35
|
+
private readonly codeBuffer;
|
|
36
|
+
private readonly checkSet;
|
|
37
|
+
private readonly onEvent?;
|
|
38
|
+
private readonly adaptiveDepth;
|
|
39
|
+
private readonly entropyDetector?;
|
|
40
|
+
private events;
|
|
41
|
+
private unitsProcessed;
|
|
42
|
+
private checksRun;
|
|
43
|
+
private findingsCount;
|
|
44
|
+
private totalTimeMs;
|
|
45
|
+
private maxLatencyMs;
|
|
46
|
+
private skippedGreen;
|
|
47
|
+
private deferredAmber;
|
|
48
|
+
private immediateRed;
|
|
49
|
+
private deferredUnits;
|
|
50
|
+
/**
|
|
51
|
+
* Tracks the highest endOffset from any code unit we have processed.
|
|
52
|
+
* Used by flush() to know where unchecked trailing code begins.
|
|
53
|
+
*/
|
|
54
|
+
private coveredOffset;
|
|
55
|
+
constructor(options: StreamingVerifierOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Feed tokens from the LLM stream. Returns any verification events triggered.
|
|
58
|
+
*/
|
|
59
|
+
push(tokens: string): VerificationEvent[];
|
|
60
|
+
/**
|
|
61
|
+
* Flush the buffer — run checks on any remaining buffered code.
|
|
62
|
+
* Call at the end of the stream to verify trailing code that never
|
|
63
|
+
* reached a structural boundary (closing brace, semicolon, etc.).
|
|
64
|
+
* Also processes any deferred (amber) code units.
|
|
65
|
+
*/
|
|
66
|
+
flush(): VerificationEvent[];
|
|
67
|
+
/** Get cumulative statistics. */
|
|
68
|
+
getStats(): StreamingVerifierStats;
|
|
69
|
+
/** Get all findings (FAIL events) accumulated so far. */
|
|
70
|
+
getFindings(): VerificationEvent[];
|
|
71
|
+
/** Get the full generated code accumulated so far. */
|
|
72
|
+
getGeneratedCode(): string;
|
|
73
|
+
/** Reset all state — buffer, events, stats. */
|
|
74
|
+
reset(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Determine the adaptive verification depth for a code unit.
|
|
77
|
+
* When adaptiveDepth is disabled or no entropy detector is available,
|
|
78
|
+
* returns undefined (meaning: check everything).
|
|
79
|
+
*/
|
|
80
|
+
private getUnitDepth;
|
|
81
|
+
/**
|
|
82
|
+
* Run checks against a list of code units, accumulate stats, fire callbacks.
|
|
83
|
+
* When adaptiveDepth is enabled, routes based on BAS:
|
|
84
|
+
* green — skip formal checks (log as pass)
|
|
85
|
+
* amber — defer checks (queued for later via flushDeferred)
|
|
86
|
+
* red — run checks immediately
|
|
87
|
+
*/
|
|
88
|
+
private processUnits;
|
|
89
|
+
/**
|
|
90
|
+
* Process all deferred (amber) code units. Call this when the statement
|
|
91
|
+
* completes or at stream end to run checks on amber-queued blocks.
|
|
92
|
+
* Returns any verification events from the deferred checks.
|
|
93
|
+
*/
|
|
94
|
+
flushDeferred(): VerificationEvent[];
|
|
95
|
+
/** Get adaptive depth routing statistics. */
|
|
96
|
+
getDepthStats(): {
|
|
97
|
+
skippedGreen: number;
|
|
98
|
+
deferredAmber: number;
|
|
99
|
+
immediateRed: number;
|
|
100
|
+
pendingDeferred: number;
|
|
101
|
+
};
|
|
102
|
+
}
|