dravix-agent 0.1.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/.claude/settings.example.json +30 -0
- package/ARCHITECTURE.md +410 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/ROADMAP.md +117 -0
- package/data/vulnkb.json +666 -0
- package/dist/bin/aegis.d.ts +3 -0
- package/dist/bin/aegis.d.ts.map +1 -0
- package/dist/bin/aegis.js +489 -0
- package/dist/bin/aegis.js.map +1 -0
- package/dist/cache.d.ts +9 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +146 -0
- package/dist/cache.js.map +1 -0
- package/dist/engines/ai-sinks.d.ts +52 -0
- package/dist/engines/ai-sinks.d.ts.map +1 -0
- package/dist/engines/ai-sinks.js +204 -0
- package/dist/engines/ai-sinks.js.map +1 -0
- package/dist/engines/eslint.d.ts +9 -0
- package/dist/engines/eslint.d.ts.map +1 -0
- package/dist/engines/eslint.js +245 -0
- package/dist/engines/eslint.js.map +1 -0
- package/dist/engines/joern.d.ts +3 -0
- package/dist/engines/joern.d.ts.map +1 -0
- package/dist/engines/joern.js +98 -0
- package/dist/engines/joern.js.map +1 -0
- package/dist/engines/js-sinks.d.ts +70 -0
- package/dist/engines/js-sinks.d.ts.map +1 -0
- package/dist/engines/js-sinks.js +370 -0
- package/dist/engines/js-sinks.js.map +1 -0
- package/dist/engines/llm-critic.d.ts +130 -0
- package/dist/engines/llm-critic.d.ts.map +1 -0
- package/dist/engines/llm-critic.js +551 -0
- package/dist/engines/llm-critic.js.map +1 -0
- package/dist/engines/pragma.d.ts +20 -0
- package/dist/engines/pragma.d.ts.map +1 -0
- package/dist/engines/pragma.js +83 -0
- package/dist/engines/pragma.js.map +1 -0
- package/dist/engines/property-test.d.ts +3 -0
- package/dist/engines/property-test.d.ts.map +1 -0
- package/dist/engines/property-test.js +134 -0
- package/dist/engines/property-test.js.map +1 -0
- package/dist/engines/pyright.d.ts +10 -0
- package/dist/engines/pyright.d.ts.map +1 -0
- package/dist/engines/pyright.js +143 -0
- package/dist/engines/pyright.js.map +1 -0
- package/dist/engines/pysa.d.ts +3 -0
- package/dist/engines/pysa.d.ts.map +1 -0
- package/dist/engines/pysa.js +83 -0
- package/dist/engines/pysa.js.map +1 -0
- package/dist/engines/python-sinks.d.ts +82 -0
- package/dist/engines/python-sinks.d.ts.map +1 -0
- package/dist/engines/python-sinks.js +459 -0
- package/dist/engines/python-sinks.js.map +1 -0
- package/dist/engines/registry.d.ts +26 -0
- package/dist/engines/registry.d.ts.map +1 -0
- package/dist/engines/registry.js +70 -0
- package/dist/engines/registry.js.map +1 -0
- package/dist/engines/secret-scan.d.ts +22 -0
- package/dist/engines/secret-scan.d.ts.map +1 -0
- package/dist/engines/secret-scan.js +179 -0
- package/dist/engines/secret-scan.js.map +1 -0
- package/dist/engines/semgrep.d.ts +10 -0
- package/dist/engines/semgrep.d.ts.map +1 -0
- package/dist/engines/semgrep.js +200 -0
- package/dist/engines/semgrep.js.map +1 -0
- package/dist/engines/treesitter.d.ts +18 -0
- package/dist/engines/treesitter.d.ts.map +1 -0
- package/dist/engines/treesitter.js +135 -0
- package/dist/engines/treesitter.js.map +1 -0
- package/dist/engines/tsc.d.ts +10 -0
- package/dist/engines/tsc.d.ts.map +1 -0
- package/dist/engines/tsc.js +142 -0
- package/dist/engines/tsc.js.map +1 -0
- package/dist/engines/types.d.ts +47 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +27 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/findings.d.ts +121 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +98 -0
- package/dist/findings.js.map +1 -0
- package/dist/hooks/claude-code.d.ts +3 -0
- package/dist/hooks/claude-code.d.ts.map +1 -0
- package/dist/hooks/claude-code.js +187 -0
- package/dist/hooks/claude-code.js.map +1 -0
- package/dist/index/context.d.ts +127 -0
- package/dist/index/context.d.ts.map +1 -0
- package/dist/index/context.js +267 -0
- package/dist/index/context.js.map +1 -0
- package/dist/index/embeddings.d.ts +68 -0
- package/dist/index/embeddings.d.ts.map +1 -0
- package/dist/index/embeddings.js +570 -0
- package/dist/index/embeddings.js.map +1 -0
- package/dist/index/graph_routing.d.ts +36 -0
- package/dist/index/graph_routing.d.ts.map +1 -0
- package/dist/index/graph_routing.js +170 -0
- package/dist/index/graph_routing.js.map +1 -0
- package/dist/index/joern.d.ts +76 -0
- package/dist/index/joern.d.ts.map +1 -0
- package/dist/index/joern.js +782 -0
- package/dist/index/joern.js.map +1 -0
- package/dist/index/property-test.d.ts +88 -0
- package/dist/index/property-test.d.ts.map +1 -0
- package/dist/index/property-test.js +466 -0
- package/dist/index/property-test.js.map +1 -0
- package/dist/index/proto/scip.proto +897 -0
- package/dist/index/pysa.d.ts +91 -0
- package/dist/index/pysa.d.ts.map +1 -0
- package/dist/index/pysa.js +617 -0
- package/dist/index/pysa.js.map +1 -0
- package/dist/index/scip.d.ts +76 -0
- package/dist/index/scip.d.ts.map +1 -0
- package/dist/index/scip.js +541 -0
- package/dist/index/scip.js.map +1 -0
- package/dist/index/vulrag.d.ts +86 -0
- package/dist/index/vulrag.d.ts.map +1 -0
- package/dist/index/vulrag.js +242 -0
- package/dist/index/vulrag.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/install/claude-code.d.ts +31 -0
- package/dist/install/claude-code.d.ts.map +1 -0
- package/dist/install/claude-code.js +447 -0
- package/dist/install/claude-code.js.map +1 -0
- package/dist/lang.d.ts +5 -0
- package/dist/lang.d.ts.map +1 -0
- package/dist/lang.js +52 -0
- package/dist/lang.js.map +1 -0
- package/dist/learning/suppressions.d.ts +70 -0
- package/dist/learning/suppressions.d.ts.map +1 -0
- package/dist/learning/suppressions.js +179 -0
- package/dist/learning/suppressions.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +187 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/explain.d.ts +58 -0
- package/dist/mcp/tools/explain.d.ts.map +1 -0
- package/dist/mcp/tools/explain.js +60 -0
- package/dist/mcp/tools/explain.js.map +1 -0
- package/dist/mcp/tools/precheck.d.ts +29 -0
- package/dist/mcp/tools/precheck.d.ts.map +1 -0
- package/dist/mcp/tools/precheck.js +42 -0
- package/dist/mcp/tools/precheck.js.map +1 -0
- package/dist/mcp/tools/validate.d.ts +73 -0
- package/dist/mcp/tools/validate.d.ts.map +1 -0
- package/dist/mcp/tools/validate.js +66 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/dist/mcp/warm.d.ts +88 -0
- package/dist/mcp/warm.d.ts.map +1 -0
- package/dist/mcp/warm.js +331 -0
- package/dist/mcp/warm.js.map +1 -0
- package/dist/orchestrator.d.ts +46 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +596 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/policy.d.ts +51 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +201 -0
- package/dist/policy.js.map +1 -0
- package/dist/risk.d.ts +31 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +92 -0
- package/dist/risk.js.map +1 -0
- package/dist/stats.d.ts +72 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +217 -0
- package/dist/stats.js.map +1 -0
- package/dist/telemetry/collector.d.ts +10 -0
- package/dist/telemetry/collector.d.ts.map +1 -0
- package/dist/telemetry/collector.js +75 -0
- package/dist/telemetry/collector.js.map +1 -0
- package/dist/telemetry/consent.d.ts +9 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +42 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/installation.d.ts +2 -0
- package/dist/telemetry/installation.d.ts.map +1 -0
- package/dist/telemetry/installation.js +32 -0
- package/dist/telemetry/installation.js.map +1 -0
- package/dist/telemetry/sanitizer.d.ts +5 -0
- package/dist/telemetry/sanitizer.d.ts.map +1 -0
- package/dist/telemetry/sanitizer.js +60 -0
- package/dist/telemetry/sanitizer.js.map +1 -0
- package/dist/telemetry/types.d.ts +39 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +4 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/telemetry/uploader.d.ts +12 -0
- package/dist/telemetry/uploader.d.ts.map +1 -0
- package/dist/telemetry/uploader.js +92 -0
- package/dist/telemetry/uploader.js.map +1 -0
- package/dist/util/logger.d.ts +19 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +58 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/safe-paths.d.ts +8 -0
- package/dist/util/safe-paths.d.ts.map +1 -0
- package/dist/util/safe-paths.js +102 -0
- package/dist/util/safe-paths.js.map +1 -0
- package/dist/util/subprocess.d.ts +32 -0
- package/dist/util/subprocess.d.ts.map +1 -0
- package/dist/util/subprocess.js +137 -0
- package/dist/util/subprocess.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase-0 orchestrator: runs all available engines in parallel on one file,
|
|
3
|
+
* merges + de-duplicates findings, returns a single `Action` decision.
|
|
4
|
+
*
|
|
5
|
+
* Hard end-to-end timeout (`totalTimeoutMs`) — if any engine is still running
|
|
6
|
+
* past that, its result is dropped (the gate prefers a timely "WARN, partial"
|
|
7
|
+
* over blocking the agent indefinitely).
|
|
8
|
+
*
|
|
9
|
+
* Caches per (engine, lang, content_hash) so re-runs on the same content are
|
|
10
|
+
* effectively free.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, mkdirSync, appendFileSync } from "node:fs";
|
|
13
|
+
import { join, resolve } from "node:path";
|
|
14
|
+
import { Cache, cacheKeyForEngine } from "./cache.js";
|
|
15
|
+
import { safeRun } from "./engines/types.js";
|
|
16
|
+
import { ENGINES, STAGE2_ENGINES } from "./engines/registry.js";
|
|
17
|
+
import { buildProjectContext } from "./index/context.js";
|
|
18
|
+
import { findCallerSideRiskSignals } from "./index/graph_routing.js";
|
|
19
|
+
import { findPropertyCandidates } from "./index/property-test.js";
|
|
20
|
+
import { getIndexer } from "./index/scip.js";
|
|
21
|
+
import { getVulRag } from "./index/vulrag.js";
|
|
22
|
+
import { detectLang } from "./lang.js";
|
|
23
|
+
import { isSuppressed } from "./learning/suppressions.js";
|
|
24
|
+
import { findingMatches, loadPolicy } from "./policy.js";
|
|
25
|
+
import { decide } from "./risk.js";
|
|
26
|
+
import { getLogger } from "./util/logger.js";
|
|
27
|
+
import { safeResolve } from "./util/safe-paths.js";
|
|
28
|
+
const log = getLogger("aegis.orchestrator");
|
|
29
|
+
const DEFAULT_TOTAL_TIMEOUT_MS = 5_000;
|
|
30
|
+
const DEFAULT_PER_ENGINE_TIMEOUT_MS = 4_000;
|
|
31
|
+
const ENGINE_RESULT_CACHE_TTL_MS = 5 * 60 * 1000; // 5 min — keep through a coding session
|
|
32
|
+
/** Critic gets its own budget — claude -p --effort max routinely takes
|
|
33
|
+
* 15-60 s, far longer than DEFAULT_TOTAL_TIMEOUT_MS. Override via
|
|
34
|
+
* ``AEGIS_CRITIC_TIMEOUT_MS``. */
|
|
35
|
+
const DEFAULT_CRITIC_TIMEOUT_MS = 120_000;
|
|
36
|
+
/** Vul-RAG similarity above which we consider the file "suspicious enough"
|
|
37
|
+
* to warrant a critic call even when stage-1 had nothing. The default
|
|
38
|
+
* (0.55) was empirically chosen against the canonical CWE pattern smoke:
|
|
39
|
+
* SQLi/XSS/cmd-inj/secret-leak patterns all hit ≥ 0.55 on top-1; benign
|
|
40
|
+
* code lands < 0.4. Override with ``AEGIS_CRITIC_ROUTE_VULRAG``. */
|
|
41
|
+
const DEFAULT_VULRAG_ROUTE_THRESHOLD = 0.55;
|
|
42
|
+
/** Lightweight detection: does the file use a concurrency primitive in a
|
|
43
|
+
* way that warrants the critic? Cheap regex pass — no AST, no I/O.
|
|
44
|
+
*
|
|
45
|
+
* Hits one of:
|
|
46
|
+
* - Python: threading|asyncio|multiprocessing|concurrent.futures import
|
|
47
|
+
* AND .start() / await / asyncio.gather / .submit() / .map_async
|
|
48
|
+
* - JS/TS: Promise.all / Promise.race / Worker / new Worker / cluster.fork
|
|
49
|
+
*
|
|
50
|
+
* Race conditions / missing-await / ordering bugs almost never show up in
|
|
51
|
+
* stage-1 static engines without a CPG (Joern / Pysa) and Vul-RAG often
|
|
52
|
+
* misses them too — but the critic catches them reliably when invoked
|
|
53
|
+
* (verified via AEGIS_CRITIC_FORCE on the redteam/v2_18/worker.py case
|
|
54
|
+
* which had 0 stage-1 findings but 2 critic findings when forced).
|
|
55
|
+
*/
|
|
56
|
+
function concurrencyHint(content, lang) {
|
|
57
|
+
if (lang === "python") {
|
|
58
|
+
const importsThreading = /\b(?:from\s+threading\b|import\s+threading\b|from\s+asyncio\b|import\s+asyncio\b|from\s+multiprocessing\b|import\s+multiprocessing\b|from\s+concurrent\.futures\b)/.test(content);
|
|
59
|
+
if (!importsThreading)
|
|
60
|
+
return false;
|
|
61
|
+
const dispatches = /\b(?:Thread\s*\(|Process\s*\(|\.start\s*\(\s*\)|asyncio\.gather|asyncio\.create_task|asyncio\.run\s*\(|await\s+|\.submit\s*\(|\.map\s*\(|\.map_async\s*\()/.test(content);
|
|
62
|
+
return dispatches;
|
|
63
|
+
}
|
|
64
|
+
if (lang === "javascript" || lang === "typescript") {
|
|
65
|
+
const concurrencyApi = /\b(?:Promise\.(?:all|race|allSettled|any)|new\s+Worker\s*\(|cluster\.fork\s*\(|worker_threads|setImmediate\s*\()/.test(content);
|
|
66
|
+
return concurrencyApi;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
/** Routing predicate: should we spend an LLM message on this file?
|
|
71
|
+
*
|
|
72
|
+
* Decision matrix (first hit wins):
|
|
73
|
+
* AEGIS_CRITIC_DISABLE=1 → never (kill switch)
|
|
74
|
+
* AEGIS_CRITIC_FORCE=1 → always (debugging / force-check)
|
|
75
|
+
* stage-1 finding → run
|
|
76
|
+
* caller_of_risky → run + carry hits to the critic.
|
|
77
|
+
* V2-14 eval found 2/7 cross-file bugs were
|
|
78
|
+
* missed because the caller file (e.g. a
|
|
79
|
+
* route) had no obvious pattern in isolation
|
|
80
|
+
* but imported a function Joern had already
|
|
81
|
+
* flagged. This signal closes that gap.
|
|
82
|
+
* property_candidate → run (Python math/money names)
|
|
83
|
+
* vulrag_signal → run (security KB semantic match)
|
|
84
|
+
* else → skip
|
|
85
|
+
*
|
|
86
|
+
* Vul-RAG check costs ~30 ms after warm; candidate scan + import parse
|
|
87
|
+
* are each <1 ms. Phase 4 will replace the whole stack with the 150M
|
|
88
|
+
* router for sharper classification.
|
|
89
|
+
*/
|
|
90
|
+
async function decideStage2(stage1Findings, content, lang, projectRoot) {
|
|
91
|
+
if (process.env.AEGIS_CRITIC_DISABLE === "1") {
|
|
92
|
+
return { run: false, reason: "disabled" };
|
|
93
|
+
}
|
|
94
|
+
if (process.env.AEGIS_CRITIC_FORCE === "1") {
|
|
95
|
+
return { run: true, reason: "forced" };
|
|
96
|
+
}
|
|
97
|
+
if (stage1Findings.length > 0) {
|
|
98
|
+
return { run: true, reason: "stage1_findings" };
|
|
99
|
+
}
|
|
100
|
+
// Graph-aware routing: file imports a module that ALREADY has Joern
|
|
101
|
+
// or Pysa findings. The critic on this file needs to see THIS file's
|
|
102
|
+
// usage of that risky module — without this, the route file looks
|
|
103
|
+
// clean alone but the SQLi flowing into the imported module isn't
|
|
104
|
+
// even routed for review.
|
|
105
|
+
if (projectRoot) {
|
|
106
|
+
try {
|
|
107
|
+
const hits = findCallerSideRiskSignals(content, projectRoot, lang);
|
|
108
|
+
if (hits.length > 0) {
|
|
109
|
+
log.debug("stage2 routing: caller_of_risky", {
|
|
110
|
+
n_hits: hits.length,
|
|
111
|
+
modules: [...new Set(hits.map((h) => h.importedModule))].slice(0, 5),
|
|
112
|
+
source_engines: [...new Set(hits.map((h) => h.sourceEngine))],
|
|
113
|
+
});
|
|
114
|
+
return { run: true, reason: "caller_of_risky", callerHits: hits };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
log.debug("caller-of-risky check failed; falling through", { err: String(err) });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Property-test signal: Python file with at least one high-risk function
|
|
122
|
+
// (math / money / auth name pattern). Cheap regex pass, no I/O.
|
|
123
|
+
if (lang === "python") {
|
|
124
|
+
const cands = findPropertyCandidates(content, 1);
|
|
125
|
+
if (cands.length > 0) {
|
|
126
|
+
log.debug("stage2 routing: python property-test candidate", { fn: cands[0].name });
|
|
127
|
+
return { run: true, reason: "property_candidate" };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Concurrency-hint signal: race conditions / missing-await / ordering
|
|
131
|
+
// bugs almost never surface in stage-1 static engines without a CPG,
|
|
132
|
+
// and Vul-RAG often misses them too — but the critic catches them
|
|
133
|
+
// reliably when invoked.
|
|
134
|
+
if (concurrencyHint(content, lang)) {
|
|
135
|
+
log.debug("stage2 routing: concurrency primitives detected");
|
|
136
|
+
return { run: true, reason: "concurrency_hint" };
|
|
137
|
+
}
|
|
138
|
+
// Vul-RAG fallback signal — Semgrep / Pyright / etc. may be absent.
|
|
139
|
+
try {
|
|
140
|
+
const threshold = Number(process.env.AEGIS_CRITIC_ROUTE_VULRAG ?? DEFAULT_VULRAG_ROUTE_THRESHOLD);
|
|
141
|
+
if (!Number.isFinite(threshold) || threshold > 1 || threshold < 0) {
|
|
142
|
+
return { run: false, reason: "bad_threshold" };
|
|
143
|
+
}
|
|
144
|
+
const rag = getVulRag();
|
|
145
|
+
const hits = await rag.topK(content.slice(0, 4000), 1, {
|
|
146
|
+
...(lang !== "unknown" ? { language: String(lang) } : {}),
|
|
147
|
+
minSimilarity: threshold,
|
|
148
|
+
});
|
|
149
|
+
if (hits.length > 0) {
|
|
150
|
+
log.debug("critic routing: vulrag top-1 above threshold", {
|
|
151
|
+
cwe: hits[0].entry.cwe,
|
|
152
|
+
similarity: hits[0].similarity,
|
|
153
|
+
threshold,
|
|
154
|
+
});
|
|
155
|
+
return { run: true, reason: "vulrag_signal" };
|
|
156
|
+
}
|
|
157
|
+
return { run: false, reason: "no_signal" };
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
log.debug("critic routing: vulrag check failed; default to skip", { err: String(err) });
|
|
161
|
+
return { run: false, reason: "vulrag_unavailable" };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export async function runGate(input) {
|
|
165
|
+
const t0 = Date.now();
|
|
166
|
+
const totalTimeout = input.totalTimeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS;
|
|
167
|
+
const lang = detectLang(input.filePath);
|
|
168
|
+
// Safety: resolve the file path against the project root if given. When the
|
|
169
|
+
// caller explicitly opts out (ad-hoc scan), only the denylist applies.
|
|
170
|
+
const containmentRoot = input.enforceContainment === false ? undefined : input.projectRoot;
|
|
171
|
+
const sp = safeResolve(input.filePath, containmentRoot);
|
|
172
|
+
if (!sp.ok) {
|
|
173
|
+
log.warn("path check failed", { file: input.filePath, reason: sp.reason });
|
|
174
|
+
return {
|
|
175
|
+
filePath: input.filePath,
|
|
176
|
+
lang,
|
|
177
|
+
decision: {
|
|
178
|
+
action: "block",
|
|
179
|
+
driving: null,
|
|
180
|
+
summary: `BLOCK — refused to scan path (${sp.reason}).`,
|
|
181
|
+
blockCount: 1,
|
|
182
|
+
warnCount: 0,
|
|
183
|
+
totalFindings: 0,
|
|
184
|
+
},
|
|
185
|
+
findings: [],
|
|
186
|
+
engineResults: [],
|
|
187
|
+
durationMs: Date.now() - t0,
|
|
188
|
+
truncated: false,
|
|
189
|
+
pathCheck: { ok: false, reason: sp.reason ?? "denied" },
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const enginesAll = input.engines ?? ENGINES;
|
|
193
|
+
// Engine availability is cached per process inside each engine impl;
|
|
194
|
+
// the warm path additionally supplies an override map that was probed
|
|
195
|
+
// once at server boot, so we don't even cross the engine boundary.
|
|
196
|
+
const enginesAvailable = [];
|
|
197
|
+
for (const e of enginesAll) {
|
|
198
|
+
const override = input.availabilityOverride?.get(e.name);
|
|
199
|
+
let ok;
|
|
200
|
+
if (override !== undefined) {
|
|
201
|
+
ok = override;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
ok = await e.available();
|
|
205
|
+
}
|
|
206
|
+
if (ok)
|
|
207
|
+
enginesAvailable.push(e);
|
|
208
|
+
else
|
|
209
|
+
log.debug("engine unavailable, skipping", { engine: e.name });
|
|
210
|
+
}
|
|
211
|
+
const cache = input.noCache ? null : new Cache(input.projectRoot);
|
|
212
|
+
// Per-engine wrapper: cache check → safeRun → cache write.
|
|
213
|
+
const runOne = async (engine) => {
|
|
214
|
+
if (cache) {
|
|
215
|
+
const ck = cacheKeyForEngine(engine.name, lang, input.content);
|
|
216
|
+
const hit = await cache.get(ck);
|
|
217
|
+
if (hit) {
|
|
218
|
+
log.debug("cache hit", { engine: engine.name });
|
|
219
|
+
return hit;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const eInput = {
|
|
223
|
+
filePath: sp.resolved,
|
|
224
|
+
content: input.content,
|
|
225
|
+
lang,
|
|
226
|
+
...(input.projectRoot !== undefined ? { projectRoot: input.projectRoot } : {}),
|
|
227
|
+
timeoutMs: Math.min(DEFAULT_PER_ENGINE_TIMEOUT_MS, totalTimeout),
|
|
228
|
+
};
|
|
229
|
+
const res = await safeRun(engine, eInput);
|
|
230
|
+
if (cache && !res.unavailable) {
|
|
231
|
+
const ck = cacheKeyForEngine(engine.name, lang, input.content);
|
|
232
|
+
await cache.put(ck, res, ENGINE_RESULT_CACHE_TTL_MS);
|
|
233
|
+
}
|
|
234
|
+
return res;
|
|
235
|
+
};
|
|
236
|
+
// Race the parallel engine fleet against the overall budget.
|
|
237
|
+
const allPromise = Promise.allSettled(enginesAvailable.map(runOne));
|
|
238
|
+
const timeoutPromise = new Promise((r) => setTimeout(() => r("TIMEOUT"), totalTimeout));
|
|
239
|
+
const raceResult = await Promise.race([allPromise, timeoutPromise]);
|
|
240
|
+
let engineResults;
|
|
241
|
+
let truncated = false;
|
|
242
|
+
if (raceResult === "TIMEOUT") {
|
|
243
|
+
// Take whatever finished so far. We do this by re-running the same
|
|
244
|
+
// promise with Promise.allSettled (already in flight) AFTER awaiting it,
|
|
245
|
+
// because Promise.allSettled never rejects — but here we've already
|
|
246
|
+
// raced and lost. We accept the engines we got back so far by querying
|
|
247
|
+
// their cached results from the same input. If none, we degrade to allow.
|
|
248
|
+
truncated = true;
|
|
249
|
+
log.warn("orchestrator timeout — degraded run", { totalTimeout });
|
|
250
|
+
engineResults = [];
|
|
251
|
+
// Best-effort: give the in-flight set a brief tail to finish so we don't
|
|
252
|
+
// toss completed work.
|
|
253
|
+
const tail = await Promise.race([
|
|
254
|
+
allPromise,
|
|
255
|
+
new Promise((r) => setTimeout(() => r("GIVEUP"), 250)),
|
|
256
|
+
]);
|
|
257
|
+
if (tail !== "GIVEUP") {
|
|
258
|
+
engineResults = tail
|
|
259
|
+
.filter((s) => s.status === "fulfilled")
|
|
260
|
+
.map((s) => s.value);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
engineResults = raceResult
|
|
265
|
+
.filter((s) => s.status === "fulfilled")
|
|
266
|
+
.map((s) => s.value);
|
|
267
|
+
}
|
|
268
|
+
// Merge + dedup STAGE-1 findings. Dedup key = id (engine+file+line+rule),
|
|
269
|
+
// so identical findings from the same engine across cache + live runs collapse.
|
|
270
|
+
const seen = new Set();
|
|
271
|
+
const stage1Findings = [];
|
|
272
|
+
for (const r of engineResults) {
|
|
273
|
+
for (const f of r.findings) {
|
|
274
|
+
if (seen.has(f.id))
|
|
275
|
+
continue;
|
|
276
|
+
seen.add(f.id);
|
|
277
|
+
stage1Findings.push(f);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Phase 1: enrich the report with cross-file context from the SCIP index,
|
|
281
|
+
// when a project root is given. Best-effort — never throws / never blocks.
|
|
282
|
+
// The indexer is lazy: if no index exists yet, the block reports
|
|
283
|
+
// ``available: false`` and the caller can run ``aegis index`` to enable it.
|
|
284
|
+
// Built BEFORE stage-2 so the critic can consume it.
|
|
285
|
+
let projectContext;
|
|
286
|
+
if (input.projectRoot) {
|
|
287
|
+
try {
|
|
288
|
+
const indexer = getIndexer();
|
|
289
|
+
projectContext = await buildProjectContext(indexer, {
|
|
290
|
+
filePath: input.filePath,
|
|
291
|
+
content: input.content,
|
|
292
|
+
lang,
|
|
293
|
+
projectRoot: input.projectRoot,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
log.debug("project context build failed", { err: String(err) });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Stage 2 — LLM critic. Sequential to stage 1, runs only when the routing
|
|
301
|
+
// predicate says it's worth a Claude message. The critic has its own
|
|
302
|
+
// budget (much longer than the stage-1 cap) because --effort max can take
|
|
303
|
+
// a full minute on cold calls. Crashes here are isolated — they never
|
|
304
|
+
// fail-close the whole gate.
|
|
305
|
+
const findings = [...stage1Findings];
|
|
306
|
+
const allEngineResults = [...engineResults];
|
|
307
|
+
const stage2EnginesToRun = input.engines === undefined ? STAGE2_ENGINES : [];
|
|
308
|
+
if (stage2EnginesToRun.length > 0) {
|
|
309
|
+
const decision = await decideStage2(stage1Findings, input.content, lang, input.projectRoot);
|
|
310
|
+
if (decision.run) {
|
|
311
|
+
log.debug("stage2 routing", { reason: decision.reason });
|
|
312
|
+
// Surface caller-of-risky hits as synthetic priorFindings so the
|
|
313
|
+
// critic's prompt explicitly names the risky import. These never
|
|
314
|
+
// hit the audit log or contribute to the natural decide() rank —
|
|
315
|
+
// they're context only. The synthetic finding's rule_id makes
|
|
316
|
+
// its provenance obvious if it shows up in a debug dump.
|
|
317
|
+
if (decision.callerHits && decision.callerHits.length > 0) {
|
|
318
|
+
for (const h of decision.callerHits.slice(0, 5)) {
|
|
319
|
+
stage1Findings.push({
|
|
320
|
+
...h.finding,
|
|
321
|
+
// Annotate with the import that pulled this finding into the
|
|
322
|
+
// current file's blast radius — the critic can quote this back.
|
|
323
|
+
message: `[via import '${h.importedModule}' resolved to ${h.resolvedFile}] ` +
|
|
324
|
+
h.finding.message,
|
|
325
|
+
// Synthesise a distinct id so dedup doesn't drop it.
|
|
326
|
+
id: (h.finding.id.slice(0, 8) + h.importedModule.slice(0, 8).padEnd(8, "0"))
|
|
327
|
+
.toLowerCase()
|
|
328
|
+
.replace(/[^0-9a-f]/g, "0"),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const criticTimeoutMs = Number(process.env.AEGIS_CRITIC_TIMEOUT_MS ?? DEFAULT_CRITIC_TIMEOUT_MS) || DEFAULT_CRITIC_TIMEOUT_MS;
|
|
333
|
+
for (const e of stage2EnginesToRun) {
|
|
334
|
+
const stage2Override = input.availabilityOverride?.get(e.name);
|
|
335
|
+
const stage2Ok = stage2Override !== undefined ? stage2Override : await e.available();
|
|
336
|
+
if (!stage2Ok) {
|
|
337
|
+
log.debug("stage2 engine unavailable", { engine: e.name });
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
// Cache the critic result via the same per-(engine, lang, content_hash)
|
|
341
|
+
// key the stage-1 pipeline uses. The critic itself ALSO writes a
|
|
342
|
+
// finer-grained cache (keyed on findings + context + vulrag hashes),
|
|
343
|
+
// so this layer is a free fast-path for "same file content, same
|
|
344
|
+
// stage-1 verdict twice in a row".
|
|
345
|
+
let cachedHit = null;
|
|
346
|
+
if (cache) {
|
|
347
|
+
const ck = cacheKeyForEngine(e.name, lang, input.content);
|
|
348
|
+
cachedHit = (await cache.get(ck)) ?? null;
|
|
349
|
+
}
|
|
350
|
+
let res;
|
|
351
|
+
if (cachedHit) {
|
|
352
|
+
log.debug("cache hit", { engine: e.name });
|
|
353
|
+
res = cachedHit;
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
const eInput = {
|
|
357
|
+
filePath: sp.resolved,
|
|
358
|
+
content: input.content,
|
|
359
|
+
lang,
|
|
360
|
+
...(input.projectRoot !== undefined ? { projectRoot: input.projectRoot } : {}),
|
|
361
|
+
timeoutMs: criticTimeoutMs,
|
|
362
|
+
priorFindings: stage1Findings,
|
|
363
|
+
...(projectContext ? { projectContext } : {}),
|
|
364
|
+
};
|
|
365
|
+
res = await safeRun(e, eInput);
|
|
366
|
+
if (cache && !res.unavailable) {
|
|
367
|
+
const ck = cacheKeyForEngine(e.name, lang, input.content);
|
|
368
|
+
await cache.put(ck, res, ENGINE_RESULT_CACHE_TTL_MS);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
allEngineResults.push(res);
|
|
372
|
+
for (const f of res.findings) {
|
|
373
|
+
if (seen.has(f.id))
|
|
374
|
+
continue;
|
|
375
|
+
seen.add(f.id);
|
|
376
|
+
findings.push(f);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
log.debug("stage2 skipped by routing predicate", {
|
|
382
|
+
reason: decision.reason,
|
|
383
|
+
stage1FindingCount: stage1Findings.length,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// ── Critic-FP override ───────────────────────────────────────────────
|
|
388
|
+
// The LLM critic can emit `critic.fp.<rule_id>` or `critic.fp.<engine>`
|
|
389
|
+
// findings to declare a deterministic finding a false positive. Honor
|
|
390
|
+
// these by DROPPING the original finding at the same (file, line ±2).
|
|
391
|
+
// Without this, a deterministic severity:high finding overrides the
|
|
392
|
+
// critic's FP severity:info marker — and the file is wrongly blocked.
|
|
393
|
+
const fpMarkers = [];
|
|
394
|
+
for (const f of findings) {
|
|
395
|
+
if (f.engine === "llm-critic" && f.rule_id.startsWith("critic.fp.")) {
|
|
396
|
+
fpMarkers.push({
|
|
397
|
+
rulePart: f.rule_id.slice("critic.fp.".length),
|
|
398
|
+
...(f.line !== undefined ? { line: f.line } : {}),
|
|
399
|
+
file: f.file,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (fpMarkers.length > 0) {
|
|
404
|
+
const surviving = [];
|
|
405
|
+
for (const f of findings) {
|
|
406
|
+
if (f.engine === "llm-critic") {
|
|
407
|
+
surviving.push(f);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
const overridden = fpMarkers.some((m) => {
|
|
411
|
+
// Match rule_id OR engine name OR engine-rule combo OR rule_id
|
|
412
|
+
// starts with the critic's named part (e.g. "child-process-exec"
|
|
413
|
+
// matches "child-process-exec-tainted").
|
|
414
|
+
const exactRuleMatch = m.rulePart === f.rule_id ||
|
|
415
|
+
m.rulePart === `${f.engine}-${f.rule_id}` ||
|
|
416
|
+
(f.rule_id.length > 0 && m.rulePart.includes(f.rule_id)) ||
|
|
417
|
+
(m.rulePart.length > 3 && f.rule_id.startsWith(m.rulePart));
|
|
418
|
+
const engineOnlyMatch = m.rulePart === f.engine;
|
|
419
|
+
if (!exactRuleMatch && !engineOnlyMatch)
|
|
420
|
+
return false;
|
|
421
|
+
// Line proximity: when rule_id matches exactly we trust the critic's
|
|
422
|
+
// intent across a wider window (±10 lines — the critic often points
|
|
423
|
+
// at the FUNCTION the FP lives in, not the exact RHS). When only
|
|
424
|
+
// the ENGINE matches (e.g. "critic.fp.eslint" → any eslint finding),
|
|
425
|
+
// we still require some proximity — ±15 — so unrelated findings on
|
|
426
|
+
// distant lines aren't swept up. Missing line on either side waives
|
|
427
|
+
// the check (treat as match).
|
|
428
|
+
if (m.line === undefined || f.line === undefined)
|
|
429
|
+
return true;
|
|
430
|
+
const tolerance = exactRuleMatch ? 10 : 15;
|
|
431
|
+
return Math.abs(m.line - f.line) <= tolerance;
|
|
432
|
+
});
|
|
433
|
+
if (overridden) {
|
|
434
|
+
log.debug("critic FP override: dropping deterministic finding", {
|
|
435
|
+
engine: f.engine,
|
|
436
|
+
rule_id: f.rule_id,
|
|
437
|
+
line: f.line,
|
|
438
|
+
});
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
surviving.push(f);
|
|
442
|
+
}
|
|
443
|
+
findings.length = 0;
|
|
444
|
+
findings.push(...surviving);
|
|
445
|
+
}
|
|
446
|
+
// ── Phase 3 productionization filters ────────────────────────────────
|
|
447
|
+
// Apply (in order, before risk scoring):
|
|
448
|
+
// 1. ``ignore`` from policy → drop the finding entirely
|
|
449
|
+
// 2. Active suppressions → drop the finding entirely
|
|
450
|
+
// 3. ``warn`` from policy → tag for downgrade in risk decision
|
|
451
|
+
// 4. ``block`` from policy → tag for force-block in risk decision
|
|
452
|
+
//
|
|
453
|
+
// Tagging is via a side map (forceBlock / forceWarn id sets) that the
|
|
454
|
+
// decide() shim uses; we keep the Finding shape pristine.
|
|
455
|
+
const policy = input.projectRoot
|
|
456
|
+
? loadPolicy(input.projectRoot)
|
|
457
|
+
: { block: new Set(), warn: new Set(), ignore: new Set(), sourcePath: null };
|
|
458
|
+
const beforeFilterCount = findings.length;
|
|
459
|
+
const forceBlock = new Set();
|
|
460
|
+
const forceWarn = new Set();
|
|
461
|
+
const survivingFindings = [];
|
|
462
|
+
for (const f of findings) {
|
|
463
|
+
// 1. policy.ignore wins outright.
|
|
464
|
+
if (findingMatches(f.cwe, f.rule_id, policy.ignore)) {
|
|
465
|
+
log.debug("policy: ignored", { id: f.id, cwe: f.cwe, rule: f.rule_id });
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
// 2. user-added suppression.
|
|
469
|
+
if (input.projectRoot && isSuppressed(input.projectRoot, f.id)) {
|
|
470
|
+
log.debug("suppression: filtered", { id: f.id });
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
// 3 / 4. policy.warn / policy.block → tag, but keep the finding.
|
|
474
|
+
if (findingMatches(f.cwe, f.rule_id, policy.block)) {
|
|
475
|
+
forceBlock.add(f.id);
|
|
476
|
+
}
|
|
477
|
+
else if (findingMatches(f.cwe, f.rule_id, policy.warn)) {
|
|
478
|
+
forceWarn.add(f.id);
|
|
479
|
+
}
|
|
480
|
+
survivingFindings.push(f);
|
|
481
|
+
}
|
|
482
|
+
const filteredCount = beforeFilterCount - survivingFindings.length;
|
|
483
|
+
if (filteredCount > 0) {
|
|
484
|
+
log.debug("findings filtered by policy/suppression", {
|
|
485
|
+
before: beforeFilterCount,
|
|
486
|
+
after: survivingFindings.length,
|
|
487
|
+
filtered: filteredCount,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
const decision = decideWithPolicy(survivingFindings, forceBlock, forceWarn);
|
|
491
|
+
const durationMs = Date.now() - t0;
|
|
492
|
+
const report = {
|
|
493
|
+
filePath: input.filePath,
|
|
494
|
+
lang,
|
|
495
|
+
decision,
|
|
496
|
+
findings: survivingFindings,
|
|
497
|
+
engineResults: allEngineResults,
|
|
498
|
+
durationMs,
|
|
499
|
+
truncated,
|
|
500
|
+
pathCheck: { ok: true, resolved: sp.resolved },
|
|
501
|
+
...(projectContext ? { projectContext } : {}),
|
|
502
|
+
};
|
|
503
|
+
// Append-only audit log (no PII; just decision + file + findings count).
|
|
504
|
+
appendAudit(input.projectRoot, report);
|
|
505
|
+
// Telemetry enqueue (opt-in, sanitized). Awaited so per-call CLI processes
|
|
506
|
+
// (aegis scan, aegis hook) actually populate the buffer before exit.
|
|
507
|
+
// The collector itself short-circuits when consent is OFF, so the cost when
|
|
508
|
+
// disabled is just one dynamic import (~0.5ms). MCP/long-running uses the
|
|
509
|
+
// same path with no observable extra latency.
|
|
510
|
+
try {
|
|
511
|
+
const { enqueueReport } = await import("./telemetry/collector.js");
|
|
512
|
+
enqueueReport(input.content, report);
|
|
513
|
+
}
|
|
514
|
+
catch (err) {
|
|
515
|
+
log.debug("telemetry enqueue failed", { err: String(err) });
|
|
516
|
+
}
|
|
517
|
+
return report;
|
|
518
|
+
}
|
|
519
|
+
/** Apply policy-as-code overrides to the natural risk decision:
|
|
520
|
+
*
|
|
521
|
+
* - If any surviving finding is in ``forceBlock``, decision MUST be "block"
|
|
522
|
+
* (driving = first such finding so the user sees what triggered it).
|
|
523
|
+
* - Else if natural decision was "block" AND every block-eligible finding
|
|
524
|
+
* is in ``forceWarn``, downgrade to "warn".
|
|
525
|
+
* - Else: pass through the natural decision unchanged.
|
|
526
|
+
*
|
|
527
|
+
* Confidence/severity bookkeeping in the returned ActionDecision stays
|
|
528
|
+
* truthful — we don't lie about counts, only about the gate verdict.
|
|
529
|
+
*/
|
|
530
|
+
function decideWithPolicy(findings, forceBlock, forceWarn) {
|
|
531
|
+
const natural = decide(findings);
|
|
532
|
+
// 1. policy.block — if any matching finding exists, force block.
|
|
533
|
+
if (forceBlock.size > 0) {
|
|
534
|
+
const blockTrigger = findings.find((f) => forceBlock.has(f.id));
|
|
535
|
+
if (blockTrigger) {
|
|
536
|
+
return {
|
|
537
|
+
action: "block",
|
|
538
|
+
driving: blockTrigger,
|
|
539
|
+
summary: `BLOCK (policy) — ${blockTrigger.engine}:${blockTrigger.rule_id} matched policy.block`,
|
|
540
|
+
blockCount: natural.blockCount + (natural.action === "block" ? 0 : 1),
|
|
541
|
+
warnCount: natural.warnCount,
|
|
542
|
+
totalFindings: natural.totalFindings,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
// 2. policy.warn downgrade — only kicks in when natural decision was block.
|
|
547
|
+
if (natural.action === "block" && natural.driving && forceWarn.has(natural.driving.id)) {
|
|
548
|
+
// Look for any OTHER finding still triggering block; if none, downgrade.
|
|
549
|
+
const anyOtherBlocker = findings.some((f) => f.id !== natural.driving.id &&
|
|
550
|
+
!forceWarn.has(f.id) &&
|
|
551
|
+
(f.severity === "critical" || f.severity === "high"));
|
|
552
|
+
if (!anyOtherBlocker) {
|
|
553
|
+
return {
|
|
554
|
+
action: "warn",
|
|
555
|
+
driving: natural.driving,
|
|
556
|
+
summary: `WARN (policy downgrade) — ${natural.driving.engine}:${natural.driving.rule_id} matched policy.warn`,
|
|
557
|
+
blockCount: 0,
|
|
558
|
+
warnCount: natural.warnCount + 1,
|
|
559
|
+
totalFindings: natural.totalFindings,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return natural;
|
|
564
|
+
}
|
|
565
|
+
function appendAudit(projectRoot, report) {
|
|
566
|
+
try {
|
|
567
|
+
const dir = resolve(projectRoot ?? process.cwd(), ".aegis");
|
|
568
|
+
if (!existsSync(dir))
|
|
569
|
+
mkdirSync(dir, { recursive: true });
|
|
570
|
+
const row = {
|
|
571
|
+
ts: new Date().toISOString(),
|
|
572
|
+
file: report.filePath,
|
|
573
|
+
lang: report.lang,
|
|
574
|
+
action: report.decision.action,
|
|
575
|
+
duration_ms: report.durationMs,
|
|
576
|
+
truncated: report.truncated,
|
|
577
|
+
n_findings: report.findings.length,
|
|
578
|
+
n_block: report.decision.blockCount,
|
|
579
|
+
n_warn: report.decision.warnCount,
|
|
580
|
+
driving: report.decision.driving
|
|
581
|
+
? {
|
|
582
|
+
engine: report.decision.driving.engine,
|
|
583
|
+
rule_id: report.decision.driving.rule_id,
|
|
584
|
+
severity: report.decision.driving.severity,
|
|
585
|
+
confidence: report.decision.driving.confidence,
|
|
586
|
+
...(report.decision.driving.cwe ? { cwe: report.decision.driving.cwe } : {}),
|
|
587
|
+
}
|
|
588
|
+
: null,
|
|
589
|
+
};
|
|
590
|
+
appendFileSync(join(dir, "audit.jsonl"), JSON.stringify(row) + "\n", "utf8");
|
|
591
|
+
}
|
|
592
|
+
catch (err) {
|
|
593
|
+
log.debug("audit append failed", { err: String(err) });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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"}
|