复活 25 条死规则 — 执行记录 (2026-07-11)

复活 25 条死规则 — 执行记录 (2026-07-11)

根因

规则引擎 76 条内置规则中,约 25 条 matched 永远为 false(死规则),导致 inspect/optimize/repair 等能力空转。两类根因:

根因 A:condition 双重 JSON 编码(字符串陷阱)

repair-003/004/005/006optimize-002/003/004condition 写成 JSON.stringify({type:'...'})(字符串)。

引擎 _evaluateConditionconst 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_scriptgetRules_safeParseJson 解析出 row.condition_script 永远是 null → 即使手写 condition_script 也被 REPLACE 成 NULL。唯一真相源 _loadBuiltinRules() 的定义改动是正确修复路径。

修复动作(全在 server/core/rule-engine.js

  1. _syncBuiltinRules INSERT 补 condition_script:列清单加 condition_script,VALUES 加对应 ?stmt.runrule.condition_script || null。否则任何手写 condition_script 重启即被清空。
  2. 层1(去 JSON.stringify,4+3 条)repair-003/004/005/006optimize-002/003/004condition: JSON.stringify({type:...})condition: {type:...}(对象),引擎分支直接命中。
  3. 层2(补 condition_script,约 22 条):给所有引擎不支持 type 的规则加 condition_script,形式为 (ctx,data)=>{...; return true/false;}(与 _evaluateConditionrunSafeScript 签名一致)。
  • 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? trueinspect-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_validate scope(之前文档误记)。
  • 用真实 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_valuator service。引擎备用路径:execute('valuate')executed=truebuiltin-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 规则存活真实对象验证
inspect6 条 cond_script=trueHTTP: 618 问题(200 实例)
optimize4 条(去 JSON.stringify)HTTP: 4 条建议
validate6 通用 + 3 Project 专用HTTP: 真实 Part 6条、真实 Project 9条
repairPart/Vendor 闭环 + 10 条规则HTTP: Part 闭环、Vendor(真实ID) 闭环
collect5 条 cond_script=true引擎: executed=true, collect-001 命中
valuate2 条 cond_script=true引擎: executed=true, valuate-001 命中
create_postproject-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 确认端口只属于目标进程。
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁