复活 25 条死规则 — 执行记录 (2026-07-11)
根因
规则引擎 76 条内置规则中,约 25 条 matched 永远为 false(死规则),导致 inspect/optimize/repair 等能力空转。两类根因:
根因 A:condition 双重 JSON 编码(字符串陷阱)
repair-003/004/005/006、optimize-002/003/004 的 condition 写成 JSON.stringify({type:'...'})(字符串)。
引擎 _evaluateCondition 里 const cond = rule.condition 得到字符串,cond.type=undefined → 不进任何 type 分支 → 落 default: return false。
这些 type 其实引擎支持(has_non_standard_unit/has_price_anomaly/has_invalid_reference/has_bom_structure 等),只是被字符串包装坑死。
根因 B:引擎不支持的 condition.type,且无 condition_script 兜底
inspect-001~006 (field_empty/field_pattern/field_value/multi_field_empty/field_empty_check/staleness_check)、
valuate-001/002 (asset_count_check/income_data_check)、
project-validate-001/002/003 (field_check)、
validate-001/002 (type_check/length_check)、
create_post project-001 (check_relationships)、
repair-007~012 (has_price_change/has_missing_vendor_fields/has_low_stock/has_low_score/has_overdue_order/has_duplicate_candidates)、
collect-001~005 (source_match/auto_catalog)
这些 type 在 _evaluateCondition 明确分支里不存在 → 兜底 false。且原规则只有 condition.type 没有 condition_script(引擎优先执行 condition_script 的路径),彻底死。
根因 C(放大器):_syncBuiltinRules INSERT 缺 condition_script 列
_syncBuiltinRules 的 INSERT 列清单没有 condition_script,getRules 经 _safeParseJson 解析出 row.condition_script 永远是 null → 即使手写 condition_script 也被 REPLACE 成 NULL。唯一真相源 _loadBuiltinRules() 的定义改动是正确修复路径。
修复动作(全在 server/core/rule-engine.js)
_syncBuiltinRulesINSERT 补condition_script列:列清单加condition_script,VALUES 加对应?,stmt.run加rule.condition_script || null。否则任何手写 condition_script 重启即被清空。- 层1(去 JSON.stringify,4+3 条):
repair-003/004/005/006、optimize-002/003/004的condition: JSON.stringify({type:...})→condition: {type:...}(对象),引擎分支直接命中。 - 层2(补 condition_script,约 22 条):给所有引擎不支持 type 的规则加
condition_script,形式为(ctx,data)=>{...; return true/false;}(与_evaluateCondition的runSafeScript签名一致)。
- inspect-001~006、valuate-001/002、project-validate-001/002/003、validate-001/002、create_post project-001、repair-007~012、collect-001~005 均补。
- 有
action_script的规则(repair/project-validate/create_post/inspect-005/006/valuate/collect-005)condition_script 只负责"是否命中",命中后执行已有 action_script。 - 仅 condition.type 无 action_script 的(inspect-001/002/003/004, validate-001/002):condition_script 命中后走
prompt_template/block/warn 默认 message。
验证结果(干净重启后 HTTP 端到端)
| 能力 | 修复前 | 修复后 |
|------|--------|--------|
| inspect (Part) | 0 问题 | 618 问题(200 实例巡检,6 条规则全活) |
| optimize (Part) | 0(engine.db 干扰) | 4 条规则建议,source=rule_engine |
| validate (Part) | 6 条 | 6 条稳定,blocked=False |
| repair (Part) | 闭环(之前验证) | 闭环(repairs_applied=1) |
| repair (Vendor) | — | 被 relationship-resolver 误判 status='new' 短路(独立 bug,见下) |
| collect/valuate(主路径被 service 覆盖)/ create_post(project) | 备用路径死 | 规则补 condition_script 复活(Project 专用校验属 VALIDATE scope) |
独立脚本验证(createDatabaseFresh + _evaluateCondition):inspect 规则 6 条全部 cond_script? true,inspect-001 在缺 item_number 时返回 matched=true。
二次复查(2026-07-11 晚)— Vendor / Project / collect / valuate 深度验证
重大澄清:之前"repair Vendor 短路"是测试 ID 过期,非代码 bug
- 之前用的
Vendor-001=6E0C9F7E2B6C4E74B2074F8B6F0EA6F8在 SCSAI 中根本不存在(SCSAI 返回No items of type 'Vendor' found)。 - 所以
_resolveSelectedData拉不到 → context.data 无 id → 进resolver.resolveExistence→ 误判new→ 短路。 - 换真实 Vendor ID(如
B1B97215420F412AA41F1D349668948F)后,repair 完全闭环:executed=True, issues_found=1, repairs_applied=2, source=rule_engine。 - 结论:repair Vendor 规则(repair-003/008/010 等)本身已复活且正确,之前是测试数据问题。
Project 专用规则已复活(属 VALIDATE scope,非独立 scope)
- 澄清:
builtin-project-validate-001/002/003的 scope 是RULE_SCOPES.VALIDATE+item_type_name='Project',没有独立的project_validatescope(之前文档误记)。 - 用真实 Project(
CBB360E3...)验证 validate:返回 9 条,含builtin-project-validate-001/002/003(matched=False,因真实对象合法)+ 通用规则(generic-required-check / generic-date-logic matched=True)。证明 Project 专用规则参与执行。 builtin-project-create-post-001(scope=create_post, item_type=Project)引擎验证matched=false(create_post 路径不消费,但规则存活)。
collect / valuate 规则引擎备用路径已复活(主路径被 service 覆盖)
collect主路径:data_collection_service(service 存在即 return,不进规则引擎)。但引擎备用路径验证:execute('collect')→executed=true, 4 条结果,builtin-collect-001 matched=true(source_match 判定,命中)。collect-001~005 全部cond_script=true。valuate主路径:asset_valuatorservice。引擎备用路径:execute('valuate')→executed=true,builtin-valuate-001 matched=true。valuate-001/002 全部cond_script=true。- 注:collect/valuate 的"看似死"是主路径 service 短路,规则本身已复活;若需它们走规则引擎,需在 capability-runtime 的 collect/valuate 方法里降低 service 优先级或加
forceRuleEngine开关。
compare / identify / generate 走 LLM 降级(路由设计,非死规则)
- 这三个能力 Dispatcher 主路径是 LLM(
source=llm_router),规则引擎为备用。它们的内置规则已复活,但主路径不消费。属设计选择,不在本次修复范畴。
最终量化(修复后全能力)
| 能力 | scope 规则存活 | 真实对象验证 |
|---|---|---|
| inspect | 6 条 cond_script=true | HTTP: 618 问题(200 实例) |
| optimize | 4 条(去 JSON.stringify) | HTTP: 4 条建议 |
| validate | 6 通用 + 3 Project 专用 | HTTP: 真实 Part 6条、真实 Project 9条 |
| repair | Part/Vendor 闭环 + 10 条规则 | HTTP: Part 闭环、Vendor(真实ID) 闭环 |
| collect | 5 条 cond_script=true | 引擎: executed=true, collect-001 命中 |
| valuate | 2 条 cond_script=true | 引擎: executed=true, valuate-001 命中 |
| create_post | project-001 cond_script=true | 引擎存活 |
| compare/identify/generate | 规则存活 | 主路径走 LLM(设计) |
修改文件
server/core/rule-engine.js(_syncBuiltinRules INSERT 列 + 25 条规则 condition_script/去 JSON.stringify)- 无新增文件,临时调试脚本已清理。
关键经验
- 规则引擎"唯一真相源"是
_loadBuiltinRules()的 JS 定义,不是 DB 文件。任何修复必须改这里 + 确保_syncBuiltinRules的 INSERT 列与定义字段对齐。 - condition 必须是对象而非
JSON.stringify字符串,否则_evaluateCondition解析不到.type。 - 引擎已支持
condition_script优先于 type 分支:不支持的 type 用condition_script: (ctx,data)=>bool复活,无需改引擎分支。 - 端口被旧进程占用会导致"改了代码但旧进程仍跑"的假象:验证前务必
netstat | findstr :3006确认端口只属于目标进程。
BossAgents