@kenhkl/agent-moss 0.15.2 → 0.15.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/dist/cli.d.ts +10 -0
- package/dist/cli.js +140 -16
- package/dist/cli.js.map +1 -1
- package/dist/engine/coordinator.js +94 -12
- package/dist/engine/coordinator.js.map +1 -1
- package/dist/rules/l1_rules.json +7 -1
- package/dist/scenarios/__pycache__/__init__.cpython-311.pyc +0 -0
- package/dist/server.js +94 -12
- package/dist/server.js.map +1 -1
- package/dist/skills/script_execution_guard.md +14 -9
- package/dist/templates/security_judge_template.txt +7 -1
- package/package.json +1 -1
package/dist/rules/l1_rules.json
CHANGED
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
"risk_type": "script_execution",
|
|
25
25
|
"reason": "检测到强制删除文件 (rm -f /...)"
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
"pattern": "\\bln\\s+(-[a-zA-Z]+\\s+)*(?:--\\s+)?-s[a-zA-Z]*\\s+(?:--\\s+)?(/(?![a-zA-Z0-9._~])|~/\\.\\.(?:\\s|$|\\\"|'|;|&|\\)|\\]|/)|~/(?![.a-zA-Z0-9_~-])|~/$|~(?:\\s|$|\\\"|'|;|&|\\)|\\])|\\$HOME/\\.\\.(?:\\s|$|\\\"|'|;|&|\\)|\\]|/)|\\$HOME/(?![.a-zA-Z0-9_~-])|\\$HOME/$|\\$HOME(?:\\s|$|\\\"|'|;|&|\\)|\\]))",
|
|
29
|
+
"risk_level": "high",
|
|
30
|
+
"risk_type": "file_access",
|
|
31
|
+
"reason": "检测到创建指向根目录/主目录本身的符号链接(symlink 逃逸原语:链接点进入后 ../ 可穿越到根/主目录层级,配合删除/写入实现越权)"
|
|
32
|
+
},
|
|
27
33
|
{
|
|
28
34
|
"pattern": "chmod\\s+(?:(?:-[a-zA-Z]*|--)\\s+)*[0-7]{0,3}7\\b",
|
|
29
35
|
"risk_level": "critical",
|
|
@@ -867,4 +873,4 @@
|
|
|
867
873
|
"scope": "home"
|
|
868
874
|
}
|
|
869
875
|
]
|
|
870
|
-
}
|
|
876
|
+
}
|
|
Binary file
|
package/dist/server.js
CHANGED
|
@@ -1438,6 +1438,7 @@ __export(runtime_config_exports, {
|
|
|
1438
1438
|
getRuntimeConfigPath: () => getRuntimeConfigPath,
|
|
1439
1439
|
getScenarioRules: () => getScenarioRules,
|
|
1440
1440
|
hasRuntimeConfig: () => hasRuntimeConfig,
|
|
1441
|
+
invalidateRuntimeConfigCache: () => invalidateRuntimeConfigCache,
|
|
1441
1442
|
isL2CategoryEnabled: () => isL2CategoryEnabled,
|
|
1442
1443
|
isLayerEnabled: () => isLayerEnabled,
|
|
1443
1444
|
loadRuntimeConfig: () => loadRuntimeConfig,
|
|
@@ -1456,7 +1457,7 @@ __export(runtime_config_exports, {
|
|
|
1456
1457
|
updateSkillCategoryEnabled: () => updateSkillCategoryEnabled,
|
|
1457
1458
|
updateSkillEnabled: () => updateSkillEnabled
|
|
1458
1459
|
});
|
|
1459
|
-
import { readFileSync as readFileSync4, writeFileSync, existsSync as existsSync4, mkdirSync, unlinkSync, readdirSync as readdirSync3 } from "fs";
|
|
1460
|
+
import { readFileSync as readFileSync4, writeFileSync, existsSync as existsSync4, mkdirSync, unlinkSync, readdirSync as readdirSync3, statSync } from "fs";
|
|
1460
1461
|
import { join as join3 } from "path";
|
|
1461
1462
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
1462
1463
|
import { dirname as dirname3 } from "path";
|
|
@@ -1473,6 +1474,7 @@ function saveRuntimeConfig(config) {
|
|
|
1473
1474
|
const dir = p.substring(0, p.lastIndexOf("/"));
|
|
1474
1475
|
if (dir && !existsSync4(dir)) mkdirSync(dir, { recursive: true });
|
|
1475
1476
|
writeFileSync(p, JSON.stringify(config, null, 2), "utf-8");
|
|
1477
|
+
invalidateRuntimeConfigCache();
|
|
1476
1478
|
}
|
|
1477
1479
|
function emptyRuntimeConfig() {
|
|
1478
1480
|
return {
|
|
@@ -1486,6 +1488,9 @@ function emptyRuntimeConfig() {
|
|
|
1486
1488
|
scenario_rules: {}
|
|
1487
1489
|
};
|
|
1488
1490
|
}
|
|
1491
|
+
function invalidateRuntimeConfigCache() {
|
|
1492
|
+
runtimeConfigCache = null;
|
|
1493
|
+
}
|
|
1489
1494
|
function loadRuntimeConfig() {
|
|
1490
1495
|
const p = getRuntimeConfigPath();
|
|
1491
1496
|
if (!existsSync4(p)) {
|
|
@@ -1497,9 +1502,14 @@ function loadRuntimeConfig() {
|
|
|
1497
1502
|
return seeded;
|
|
1498
1503
|
}
|
|
1499
1504
|
try {
|
|
1505
|
+
const st = statSync(p);
|
|
1506
|
+
const cacheKey = `${p}|${st.mtimeMs}|${st.size}`;
|
|
1507
|
+
if (runtimeConfigCache && runtimeConfigCache.key === cacheKey) {
|
|
1508
|
+
return runtimeConfigCache.value;
|
|
1509
|
+
}
|
|
1500
1510
|
const data = JSON.parse(readFileSync4(p, "utf-8"));
|
|
1501
1511
|
const merged = mergeConfig(data, generateSourceDefaults());
|
|
1502
|
-
|
|
1512
|
+
const result = {
|
|
1503
1513
|
version: data.version || 1,
|
|
1504
1514
|
layers: {
|
|
1505
1515
|
L1_heuristic: data.layers?.L1_heuristic ?? true,
|
|
@@ -1513,6 +1523,8 @@ function loadRuntimeConfig() {
|
|
|
1513
1523
|
agent_rules: merged.agent_rules || {},
|
|
1514
1524
|
scenario_rules: merged.scenario_rules || {}
|
|
1515
1525
|
};
|
|
1526
|
+
runtimeConfigCache = { key: cacheKey, value: result };
|
|
1527
|
+
return result;
|
|
1516
1528
|
} catch {
|
|
1517
1529
|
return emptyRuntimeConfig();
|
|
1518
1530
|
}
|
|
@@ -2502,7 +2514,7 @@ function updateScenarioCategoryEnabled(scenarioId, category, enabled) {
|
|
|
2502
2514
|
saveRuntimeConfig(runtime);
|
|
2503
2515
|
return runtime;
|
|
2504
2516
|
}
|
|
2505
|
-
var __dirname4, ENV_RUNTIME_CONFIG_PATH, RUNTIME_CONFIG_DIR, RUNTIME_CONFIG_PATH, LAYER_DISABLE_ENV, DEFAULT_LAYERS, DENY_MODE_LABELS, _AGENTS_DIR_PROD, _AGENTS_DIR_DEV, _SCENARIOS_DIR_PROD, _SCENARIOS_DIR_DEV, SKILL_ID_RE;
|
|
2517
|
+
var __dirname4, ENV_RUNTIME_CONFIG_PATH, RUNTIME_CONFIG_DIR, RUNTIME_CONFIG_PATH, LAYER_DISABLE_ENV, DEFAULT_LAYERS, DENY_MODE_LABELS, runtimeConfigCache, _AGENTS_DIR_PROD, _AGENTS_DIR_DEV, _SCENARIOS_DIR_PROD, _SCENARIOS_DIR_DEV, SKILL_ID_RE;
|
|
2506
2518
|
var init_runtime_config = __esm({
|
|
2507
2519
|
"src/infra/runtime-config.ts"() {
|
|
2508
2520
|
"use strict";
|
|
@@ -2532,6 +2544,7 @@ var init_runtime_config = __esm({
|
|
|
2532
2544
|
deny_read: "\u4EC5\u62E6\u622A\u8BFB\u53D6",
|
|
2533
2545
|
deny_both: "\u8BFB\u5199\u5747\u62E6\u622A"
|
|
2534
2546
|
};
|
|
2547
|
+
runtimeConfigCache = null;
|
|
2535
2548
|
_AGENTS_DIR_PROD = join3(__dirname4, "agents");
|
|
2536
2549
|
_AGENTS_DIR_DEV = join3(__dirname4, "..", "..", "..", "agent_moss", "agents");
|
|
2537
2550
|
_SCENARIOS_DIR_PROD = join3(__dirname4, "scenarios");
|
|
@@ -2826,6 +2839,56 @@ function isInlineScriptCommand(actionDetail) {
|
|
|
2826
2839
|
const re = /(?:^|\s)(?:python|python3|python3\.\d+|perl|perl5|ruby|jruby|mruby|node|php|lua)\s+(?:-[a-zA-Z]*[cer][a-zA-Z]*\s+)/i;
|
|
2827
2840
|
return re.test(actionDetail);
|
|
2828
2841
|
}
|
|
2842
|
+
function resolvePathTokens(segment) {
|
|
2843
|
+
const out = [];
|
|
2844
|
+
const low = segment.toLowerCase();
|
|
2845
|
+
for (const m of low.matchAll(HOME_PREFIX_RE)) {
|
|
2846
|
+
const prefix = m[0];
|
|
2847
|
+
const endIdx = (m.index ?? 0) + m[0].length;
|
|
2848
|
+
const tail = low.slice(endIdx);
|
|
2849
|
+
if (!tail || !(tail[0] === "/" || tail[0] === " ")) {
|
|
2850
|
+
out.push([prefix, prefix]);
|
|
2851
|
+
continue;
|
|
2852
|
+
}
|
|
2853
|
+
const token = tail.trim().split(/\s+/)[0] || "";
|
|
2854
|
+
if (!token.startsWith("/")) continue;
|
|
2855
|
+
const cleaned = token.replace(/\/+$/, "").replace(/^['"]|['"]$/g, "");
|
|
2856
|
+
const segments = cleaned.split("/").filter((s) => s && s !== ".");
|
|
2857
|
+
if (!segments.some((s) => s === "..")) continue;
|
|
2858
|
+
let depth = 0;
|
|
2859
|
+
const kept = [];
|
|
2860
|
+
let escaped = false;
|
|
2861
|
+
for (const s of segments) {
|
|
2862
|
+
if (s === "..") {
|
|
2863
|
+
depth -= 1;
|
|
2864
|
+
if (kept.length) kept.pop();
|
|
2865
|
+
if (depth < 0) {
|
|
2866
|
+
escaped = true;
|
|
2867
|
+
depth = 0;
|
|
2868
|
+
}
|
|
2869
|
+
} else {
|
|
2870
|
+
depth += 1;
|
|
2871
|
+
kept.push(s);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
let resolved = kept.length ? "~/" + kept.join("/") : "~";
|
|
2875
|
+
if (escaped) resolved += "\uFF08\u26A0\uFE0F .. \u5F39\u6808\u8D85\u51FA\u4E3B\u76EE\u5F55\u6839\uFF0C\u5B9E\u9645\u76EE\u6807\u5728\u4E3B\u76EE\u5F55\u4E4B\u5916\uFF09";
|
|
2876
|
+
out.push([prefix + token, resolved]);
|
|
2877
|
+
}
|
|
2878
|
+
return out;
|
|
2879
|
+
}
|
|
2880
|
+
function buildPathContext(actionDetail) {
|
|
2881
|
+
if (!PATH_CONTEXT_TRIGGER_RE.test(actionDetail)) return "";
|
|
2882
|
+
const stripped = stripLiteralTextSegments(actionDetail);
|
|
2883
|
+
const lines = [];
|
|
2884
|
+
for (const seg of splitCommandSegments(stripped)) {
|
|
2885
|
+
for (const [raw, lex] of resolvePathTokens(seg)) {
|
|
2886
|
+
lines.push(`- \u547D\u4EE4\u6BB5 \`${seg.trim().slice(0, 60)}\`\uFF1A\`${raw}\` \u8BCD\u6CD5\u89E3\u6790\u4E3A \`${lex}\``);
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
if (!lines.length) return "";
|
|
2890
|
+
return "## \u8DEF\u5F84\u89E3\u6790\u4E8B\u5B9E\uFF08\u8BCD\u6CD5\u5206\u6790\uFF0C\u786E\u5B9A\u6027\u7ED3\u8BBA\uFF09\n" + lines.join("\n") + "\n\n## \u8FD0\u884C\u65F6\u672A\u9A8C\u8BC1\uFF08\u4F9B\u53C2\u8003\uFF0C\u975E\u4E8B\u5B9E\uFF09\n- \u5206\u6790\u5668\u4E0D\u8BFB\u6587\u4EF6\u7CFB\u7EDF\uFF1A\u65E0\u6CD5\u786E\u8BA4\u8DEF\u5F84\u4E2D\u7684\u4E2D\u95F4\u76EE\u5F55\u662F\u5426\u4E3A\u7B26\u53F7\u94FE\u63A5\uFF1B\u82E5\u4E2D\u95F4\u6BB5\u5728\u6267\u884C\u65F6\u662F\uFF08\u6216\u88AB\u66FF\u6362\u4E3A\uFF09\u6307\u5411\u4E3B\u76EE\u5F55\u5916\u7684\u8F6F\u94FE\uFF0C\u5B9E\u9645\u64CD\u4F5C\u76EE\u6807\u53EF\u80FD\u968F\u4E4B\u6539\u53D8\u3002\u8BCD\u6CD5\u89E3\u6790\u7ED3\u679C\u57FA\u4E8E\u6807\u51C6\u8DEF\u5F84\u8BED\u4E49\uFF0C\u4E0D\u5E94\u56E0\u731C\u6D4B\u300C\u89E3\u6790\u4F9D\u8D56\u67D0\u6BB5\u662F\u5426\u5B58\u5728\u300D\u800C\u5426\u5B9A\u5B83\u3002";
|
|
2891
|
+
}
|
|
2829
2892
|
function stripLiteralTextSegments(actionDetail) {
|
|
2830
2893
|
const writeScriptExec = />\s*[/~]\S*\.(sh|py|pl|rb)\b/.test(actionDetail) && /(?:&&|\|\||;|\n|\|)\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)/.test(actionDetail);
|
|
2831
2894
|
const pipeToInterpreter = /\|\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)\b/.test(actionDetail);
|
|
@@ -3352,7 +3415,7 @@ function checkLateralMovement(actionDetail) {
|
|
|
3352
3415
|
}
|
|
3353
3416
|
return null;
|
|
3354
3417
|
}
|
|
3355
|
-
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, SENSITIVE_EXCLUDED_PREFIXES, SEARCH_ACTION_PREFIXES, HOME_TARGET_RE, HOME_ASSIGN_RE;
|
|
3418
|
+
var INJECTION_KEYWORDS, DANGEROUS_PATTERNS, PATH_CONTEXT_TRIGGER_RE, HOME_PREFIX_RE, SENSITIVE_EXCLUDED_PREFIXES, SEARCH_ACTION_PREFIXES, HOME_TARGET_RE, HOME_ASSIGN_RE;
|
|
3356
3419
|
var init_heuristic = __esm({
|
|
3357
3420
|
"src/engine/heuristic.ts"() {
|
|
3358
3421
|
"use strict";
|
|
@@ -3380,6 +3443,8 @@ var init_heuristic = __esm({
|
|
|
3380
3443
|
description: c.reason
|
|
3381
3444
|
}));
|
|
3382
3445
|
})();
|
|
3446
|
+
PATH_CONTEXT_TRIGGER_RE = /(?:^|[;&|]\s*)(?:rm|rmdir|unlink|ln|mv|cp|dd|truncate|shred|chmod|chown)\b/i;
|
|
3447
|
+
HOME_PREFIX_RE = /(?:~|~(?=\/)|\$HOME\b|\$\{HOME\}|\/home\/[a-z0-9_.-]+)/gi;
|
|
3383
3448
|
SENSITIVE_EXCLUDED_PREFIXES = ["memory-", "skill-", "skill-manager-", "mailbox-", "app-"];
|
|
3384
3449
|
SEARCH_ACTION_PREFIXES = ["search-", "web-", "browser-", "query-", "websearch", "web_search"];
|
|
3385
3450
|
HOME_TARGET_RE = /(?:^|[\s="'($])(?:~|(?:\$home|\$\{home\}))(?:\/(?:\.\*|\*|\.)?)?(?=[\s"';}|&)]|$)/i;
|
|
@@ -4672,7 +4737,7 @@ init_esm_shims();
|
|
|
4672
4737
|
init_heuristic();
|
|
4673
4738
|
init_logic_rules();
|
|
4674
4739
|
init_inline_analyzer();
|
|
4675
|
-
import { statSync as
|
|
4740
|
+
import { statSync as statSync3, existsSync as existsSync9 } from "fs";
|
|
4676
4741
|
import { resolve as resolve8, join as join6, isAbsolute as isAbsolute2 } from "path";
|
|
4677
4742
|
import { homedir as homedir4 } from "os";
|
|
4678
4743
|
|
|
@@ -6333,7 +6398,7 @@ function extractInlineScriptPath(actionDetail) {
|
|
|
6333
6398
|
try {
|
|
6334
6399
|
const resolved = resolvePath2(tok.replace(/^['"]|['"]$/g, ""));
|
|
6335
6400
|
if (existsSync9(resolved)) {
|
|
6336
|
-
const stat =
|
|
6401
|
+
const stat = statSync3(resolved);
|
|
6337
6402
|
if (stat.isFile()) return resolved;
|
|
6338
6403
|
}
|
|
6339
6404
|
} catch {
|
|
@@ -6347,7 +6412,7 @@ function extractInlineScriptPath(actionDetail) {
|
|
|
6347
6412
|
try {
|
|
6348
6413
|
const resolved = resolvePath2(p);
|
|
6349
6414
|
if (existsSync9(resolved)) {
|
|
6350
|
-
const stat =
|
|
6415
|
+
const stat = statSync3(resolved);
|
|
6351
6416
|
if (stat.isFile()) return resolved;
|
|
6352
6417
|
}
|
|
6353
6418
|
} catch {
|
|
@@ -6363,7 +6428,7 @@ function extractInlineScriptPath(actionDetail) {
|
|
|
6363
6428
|
try {
|
|
6364
6429
|
resolved = resolvePath2(p);
|
|
6365
6430
|
if (existsSync9(resolved)) {
|
|
6366
|
-
const stat =
|
|
6431
|
+
const stat = statSync3(resolved);
|
|
6367
6432
|
if (stat.isFile()) return resolved;
|
|
6368
6433
|
}
|
|
6369
6434
|
} catch {
|
|
@@ -6574,7 +6639,7 @@ async function runLLMAnalysis(input, previous) {
|
|
|
6574
6639
|
} else {
|
|
6575
6640
|
scriptAnalysis = analyzeScriptContent(input.aNext.actionType, input.aNext.actionDetail);
|
|
6576
6641
|
}
|
|
6577
|
-
const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, previous.skipL3Hints ?? "", scriptChainText);
|
|
6642
|
+
const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, previous.skipL3Hints ?? "", scriptChainText, previous.pathContext ?? "");
|
|
6578
6643
|
logPrompt(prompt, input.aNext, previous.llmLogPath);
|
|
6579
6644
|
const result = await analyzeWithLLM(prompt, config);
|
|
6580
6645
|
if (llmCache.size >= LLM_CACHE_MAX) {
|
|
@@ -6598,7 +6663,7 @@ ${prompt}
|
|
|
6598
6663
|
console.warn("[AgentMoss] Failed to write LLM prompt to log:", e);
|
|
6599
6664
|
}
|
|
6600
6665
|
}
|
|
6601
|
-
function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, skipL3Hints = "", scriptChainText = "") {
|
|
6666
|
+
function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, skipL3Hints = "", scriptChainText = "", pathContext = "") {
|
|
6602
6667
|
const skillsText = formatSkillsForPrompt(matchedSkills);
|
|
6603
6668
|
const historyStr = input.actionHistory.map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`).join("\n") || "(\u65E0\u5386\u53F2\u64CD\u4F5C)";
|
|
6604
6669
|
const promptHistoryText = formatPromptHistory(input.promptHistory);
|
|
@@ -6606,7 +6671,7 @@ function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis,
|
|
|
6606
6671
|
const hintsText = formatHints(previous);
|
|
6607
6672
|
const securityJudgeTemplate = templates["security_judge"];
|
|
6608
6673
|
if (securityJudgeTemplate) {
|
|
6609
|
-
return securityJudgeTemplate.replaceAll("{prompt_session}", input.promptSession || "\uFF08\u672A\u63D0\u4F9B\uFF09").replaceAll("{prompt_history_text}", promptHistoryText).replaceAll("{action_history}", historyStr).replaceAll("{action_type}", input.aNext.actionType).replaceAll("{action_detail}", input.aNext.actionDetail).replaceAll("{reason}", input.reason || "\u672A\u8BF4\u660E").replaceAll("{skills_text}", skillsText).replaceAll("{hints_text}", hintsText).replaceAll("{script_analysis_text}", scriptAnalysisText).replaceAll("{skip_l3_hints}", skipL3Hints).replaceAll("{{", "{").replaceAll("}}", "}");
|
|
6674
|
+
return securityJudgeTemplate.replaceAll("{prompt_session}", input.promptSession || "\uFF08\u672A\u63D0\u4F9B\uFF09").replaceAll("{prompt_history_text}", promptHistoryText).replaceAll("{action_history}", historyStr).replaceAll("{action_type}", input.aNext.actionType).replaceAll("{action_detail}", input.aNext.actionDetail).replaceAll("{reason}", input.reason || "\u672A\u8BF4\u660E").replaceAll("{skills_text}", skillsText).replaceAll("{hints_text}", hintsText).replaceAll("{script_analysis_text}", scriptAnalysisText).replaceAll("{skip_l3_hints}", skipL3Hints).replaceAll("{path_context}", pathContext || "\uFF08\u672C\u547D\u4EE4\u65E0\u4E3B\u76EE\u5F55\u76F8\u5173\u8DEF\u5F84\u6BB5\uFF0C\u4E0D\u9002\u7528\uFF09").replaceAll("{{", "{").replaceAll("}}", "}");
|
|
6610
6675
|
}
|
|
6611
6676
|
console.warn("[AgentMoss] security_judge template missing, using sparse fallback prompt");
|
|
6612
6677
|
return `## \u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587
|
|
@@ -8989,6 +9054,21 @@ async function runAnalysis(input) {
|
|
|
8989
9054
|
if ((effectiveResult.riskLevel === "high" || effectiveResult.riskLevel === "critical") && (!skipInlineFileAccess || isCredentialPath)) {
|
|
8990
9055
|
return effectiveResult;
|
|
8991
9056
|
}
|
|
9057
|
+
} else {
|
|
9058
|
+
if (isInlineScriptCmd || isLiteralTextCmd) {
|
|
9059
|
+
const inlineJudgment = analyzeInlineScript(input.aNext.actionDetail);
|
|
9060
|
+
if (inlineJudgment.actionable && !inlineJudgment.allowed) {
|
|
9061
|
+
return {
|
|
9062
|
+
allowed: false,
|
|
9063
|
+
reason: inlineJudgment.reason,
|
|
9064
|
+
riskLevel: inlineJudgment.riskLevel,
|
|
9065
|
+
riskType: inlineJudgment.riskType,
|
|
9066
|
+
confidence: 90,
|
|
9067
|
+
source: "logic_rule",
|
|
9068
|
+
violatedLayers: ["L2.1"]
|
|
9069
|
+
};
|
|
9070
|
+
}
|
|
9071
|
+
}
|
|
8992
9072
|
}
|
|
8993
9073
|
if (isLogicRulesEnabled()) {
|
|
8994
9074
|
const formalSessions = [];
|
|
@@ -9090,12 +9170,14 @@ async function runAnalysis(input) {
|
|
|
9090
9170
|
}
|
|
9091
9171
|
let llmResult;
|
|
9092
9172
|
try {
|
|
9173
|
+
const pathContext = buildPathContext(input.aNext.actionDetail);
|
|
9093
9174
|
llmResult = await runLLMAnalysis(input, {
|
|
9094
9175
|
heuristic: heuristicResult,
|
|
9095
9176
|
logic: logicResult,
|
|
9096
9177
|
skipL3Hints,
|
|
9097
9178
|
scriptChain: scriptChain ?? void 0,
|
|
9098
|
-
llmLogPath: input.llmLogPath
|
|
9179
|
+
llmLogPath: input.llmLogPath,
|
|
9180
|
+
pathContext
|
|
9099
9181
|
});
|
|
9100
9182
|
} catch (e) {
|
|
9101
9183
|
const { getLLMFailMode: getLLMFailMode2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|