规则引擎校验结果截断 Bug 修复(2026-07-11 深夜 / 07-12 凌晨)

规则引擎校验结果截断 Bug 修复(2026-07-11 深夜 / 07-12 凌晨)

问题来源

上一轮复查发现反常:同一 item_type='Project'validateselected_ids(真实对象)返回 9 条且 blocked=False,但用 data 直传空 Project 返回 4 条且 blocked=True,而 4 条里全部 matched=False —— 矛盾(被拦截却看不到是哪条规则拦截)。

两个真实 Bug

Bug 1:block 提前返回时未把拦截规则并入 results(结果不完整)

位置:server/core/rule-engine.jsexecute() 循环。

原逻辑:

if (rule.action_type === 'block' && isBlocked) {
  return { executed: true, blocked: true, block_reason: actionResult.message, results, ... };
}

results 此时只含之前已评估且 matched=false 的规则,触发拦截的当前规则 resultItem 未 push。

后果:HTTP 返回 blocked=True,但 results 里看不到那条 matched=true 的拦截规则,block_reason 指向一条 results 中不存在的规则 → 形成“全 false 却 blocked”的悖论。

修复:

  • 返回前 results.push(resultItem)
  • 新增 blocking_rule: rule.id 字段,前端可明确知道是哪条规则拦截。

Bug 2:validate 默认 first_match 策略会隐藏后续更严重的 block 违规

execute 默认 conflict_strategy='first_match'。规则按优先级排序后,P1(warn) 规则排在 P0(block) 之前(因 priority||2 使 P0=0 归为 2,P1=1 更小),若某 warn 规则先 matched=truefirst_match 直接 break,后续 block 级必填校验(如 project-validate-001/003)永远不会被评估 → 校验结果漏报硬性违规。

后果:合法校验报告中本应标红的必填缺失被静默丢弃。

修复:默认策略按 scope 区分:

  • validate / inspectmerge(评估全部规则,收集所有违规);
  • 其余(repair/optimize 等)→ 保留 first_match(命中即应用首条自动修复,符合原意)。

block 分支仍作为终止条件(遇到首个 block 即返回),保证确定性。

验证(engine 直测 + HTTP 端到端)

  1. 空 Project(data-only):现 blocked=True, blocking_rule=builtin-project-validate-001,该规则 matched=True 出现在 results 中,悖论消除。
  2. 真实 Project(selected_ids)blocked=False,9 条结果,仅通用规则命中且 passed=True(非拦截),正确。
  3. 全能力回归:validate Part(6条,未拦截)/repair Part(1条回写)/optimize(4条)/inspect(618条) 全部正常,无回归。

附带确认(非 bug)

  • builtin-project-validate-003 要求 scheduling_method 非空:真实 SCSAI Project 的 scheduling_method 为有效 ID 引用,属真实必填字段;之前“OK Project”测试数据漏传 scheduling_method 才触发拦截,引擎行为正确。
  • HTTP validate 与 engine 直测结果集差异,原以为是“project 规则缺失”,实为 Bug2 的 first_match 提前 break 所致,现已统一。

修改文件

  • server/core/rule-engine.jsexecute() 两处(block 返回 push resultItem + blocking_rule;默认 conflict_strategy scope 化)。

MemoryService recordTrace 静默失败(同一轮发现并修复)

问题

server.err 每条请求都刷 [MemoryService] recordTrace失败: Cannot read properties of null (reading 'prepare')

capability-dispatcher 以 fire-and-forget 调用 memoryService.extractAndStoreFacts,其失败被 try/catch 吞掉,

导致所有记忆写入(trace/fact/profile)长期静默丢失,且无任何有效告警之外的可观测信号。

根因

  1. dbAdapter.init()异步且不会翻转任何同步开关(dbAdapter._initialized 始终 undefined),

_getDb_initialized 为假时返回 null。

  1. sqliteCompat.createDatabase 在 sql.js 未就绪时返回“延迟代理”,代理的 prepare_realDb 未填充时抛错;

_getDb 同步调用 prepare(...).run() 即抛,被吞 → this._db 永远为 null。

  1. recordTrace 原为同步,且 extractAndStoreFactsawait 它(先变成 Promise),

使后续 db.preparedb 仍为 null 时崩溃。

修复(server/services/memory-service.js

  • _getDb() 改为仅返回已就绪实例(无则返 null,不再吞错建库)。
  • 新增 async _ensureDb()await dbAdapter.init()dbAdapter.createDatabaseFresh(DB_PATH)(与规则引擎同款、server 内可用),再 _initTables()
  • recordTrace 改为 async,无 db 时 await this._ensureDb()
  • extractAndStoreFacts 改为 asyncawait recordTracedb 缺失时安全返回。
  • 模块导出前 memoryService._ensureDb() 预热,使读取类接口(getProfile/getFacts/getTraces)就绪。

验证

  • 重启后发起一次 validate 请求,boss_analytics.dbmemory_traces 表自动建好并写入 1 条

source=web, action=validate),server.err 不再出现 recordTrace 报错。

修改文件汇总

  • server/core/rule-engine.jsexecute() 两处 + executeOptimizerule_id
  • server/services/memory-service.js_getDb/_ensureDb/recordTrace/extractAndStoreFacts + 模块预热。
  • server/core/health-inspector.js_getDb 改用 createDatabaseFresh(规避 createDatabase 返回延迟代理、无 .run() 的建表失败)。

顺带修复 / 确认事项

1. optimize 返回缺 rule_id

executeOptimizeoptimizations.push 只带 rule: rule.name,漏 rule_id → 前端/审计看不到是哪条规则。

已在 server/core/rule-engine.jsrule_id: rule.id,重启验证返回含 rule_id=builtin-optimize-00x

2. HealthInspector 建表失败(this._db.run is not a function

health-inspector.jscompat.createDatabase(dbPath) 在 sql.js 未就绪时拿到“延迟代理”(只有 prepare/exec,无 run),

导致 _ensureTablesCREATE TABLE ... .run() 抛错、健康检查静默失败。改为 compat.createDatabaseFresh(dbPath)(真实实例,

与规则引擎/记忆服务同款),重启后 server.err 不再出现 建表失败/保存结果失败

3. 其余观察(非 bug)

  • identify 早期返回空:是测试入参错位(传 query 而非 query_type+filters),改为 query_type=listsource=rule_engine 正常返回。
  • [RuleEngine] SCSAI私有库查询失败: 未知错误:仅冷启动一次性 SCSAI 查询失败,非系统性。
  • 配置模块加载失败,使用默认配置: Cannot find module './cron-tasks':配置回退告警,无害。

4. 六能力端到端稳定验证(真实 Part,重启后)

validate / inspect / repair(auto_apply) / optimize(auto_apply 真实回写 SCSAI) / identify / generate 全部 success=OK,无运行时报错。

optimize auto_apply=true 实测回写 SCSAI 成功(SCSAI_response.success=true,name/description 被改写)。

状态

  • 全部修复完成,server 重启验证通过:六能力稳定、记忆写入恢复、健康检查表正常建好、无 recordTrace/建表/prepare 类报错。
  • 无残留独立 bug。
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁