规则引擎 ↔ SCSAI 同步架构与运维手册
规则引擎 ↔ SCSAI 同步架构与运维手册
> 最后更新:2026-07-23 > 适用代码:server/core/SCSAI-rule-sync.js、server/core/rule-engine.js、server/core/capability-runtime.js、server/scripts/sync-rules-bidirectional.js、server.js(漂移自检)
---
1. 权威源与数据流
BossAgent_Rule(2000+ 条,前缀 bossagent_ 字段)。server/data/rule_engine.db 的 sciot_rules_v2 表(运行时引擎实际读取的库)。SCSAI → 本地:只读拉取(pull),用 item_number(= 本地 rule.id)做幂等 upsert。 - 本地 → SCSAI:回写(push),经 SCSAIRuleSync.syncRuleToSCSAI,写 BossAgent_Rule(不再是废弃的 BOS_RULE: Method)。⚠️ 历史坑(已修复,记录以防回潮)
SCSAIRuleSync 把规则写进 BOS_RULE: Method(无人读取的死路径)。现已重写为写 BossAgent_Rule。SCSAIClient → saveRule 的回写被整体跳过。现 capability-runtime.js 建 UnifiedRuleEngine 时传入 this.SCSAIClient。---
2. 字段映射(SCSAI BossAgent_Rule ↔ 本地 sciot_rules_v2)
| 本地列 | SCSAI 属性 | 说明 | |---|---|---| | id | item_number | upsert key,两端一致 | | name | name | | | description | description | | | scope | bossagent_scope | validate/repair/optimize/compare/generate/identify | | item_type_name | bossagent_item_type | 适用对象类, 表示通用 | | severity | bossagent_severity | info/warn/error | | priority | bossagent_priority | 整数 | | condition_script | bossagent_condition_script | TEXT,可空 | | action_type | bossagent_action_type | suggest/auto_fix/... | | action_config | bossagent_action_config | JSON 字符串 | | action_script | bossagent_generated_aml | TEXT,可空 | | is_active | bossagent_is_active | 0/1 | | is_builtin | bossagent_is_builtin | 0/1 | | source | bossagent_source | generated/builtin/inspect/biz/manual/SCSAI | | version | bossagent_version | 整数 | | tags | bossagent_tags | CSV 或 JSON 字符串 | | category | bossagent_category | | | SCSAI_id | id (@_id) | SCSAI item 的 GUID,回写凭证 |
关键归一化:_SCSAIVal()
SCSAI sendAML 返回的空属性不是 null,而是对象 {is_null:"1"};引用属性可能是 {keyed_name:...}。直接在代码里 value || null 兜底不生效(对象 truthy),会把 object 传进 better-sqlite3 → 绑定失败报 Too few parameter values → 整批跳过(这是此前 PULL 长期 0 条的真凶)。_SCSAIVal(v) 负责归一化:
null/undefined → nullis_null → null;含 #text/keyed_name/value → 取之;其它 → JSON.stringify 落 TEXT 列---
3. 同步脚本
server/scripts/sync-rules-bidirectional.js:
node server/scripts/sync-rules-bidirectional.js # 默认:pull(SCSAI → 本地) node server/scripts/sync-rules-bidirectional.js --push # 本地 → SCSAI(仅 is_builtin=0) node server/scripts/sync-rules-bidirectional.js --both # 先 pull 再 push node server/scripts/sync-rules-bidirectional.js --dry # 只读漂移检查,不写任一端 SCSAIRuleSync.syncRulesFromSCSAI(SCSAIClient, engine),按 item_number upsert。maxRecords 5000。is_builtin = 0 行,逐条 syncRuleToSCSAI。id 为 NULL 的行会被跳过(无合法 id 无法映射,非 bug)。server.js 启动后约 15s 报告本地与 SCSAI 的 item_number 差异(只读 Warn,不写任一端)。---
4. 规则生命周期(CRUD 是否回写)
| 操作位置 | 是否回写 SCSAI | 现状 | |---|---|---| | 服务端 BossAgent_Rule 增删改 | 项目只 get 读,从不写 | 服务端改了 → 本地需手动 pull 才生效 | | 本地管理界面 saveRule | 是,写 BossAgent_Rule | 引擎建时传 SCSAIClient 即生效 | | 本地管理界面 deleteRule | 是(走 SCSAIRuleSync) | 同上 | | sync-rules-SCSAI-to-local.js | 只读 pull | 幂等覆盖,会覆盖本地未上 SCSAI 的修改 |
注意:pull 用 item_number 幂等覆盖。若本地有 manual 修改但 SCSAI 端没有对应 item,重跑 pull 不会删除本地多余规则,但会覆盖同名规则——本地独占修改有被覆盖风险,建议通过 push 先上行。
---
5. 运维要点
--both 做一次双向收敛。sciot_rules_v2 中 SCSAI_id 非空的条数;正常应接近本地非垃圾规则总数。id IS NULL 的本地规则无法 push,需先赋予语义化 id(如 biz-repair-xxx-001)。[RuleDrift],出现 WARN 即两端分叉,需 --both 修复。action_config/tags 必须是合法 JSON 或 CSV;inspect 类规则的 action_config 允许 key:value 文本(引擎有专门解析)。rule_engine.db 是运行时产物,被 .gitignore 排除;可随时用 --both 从 SCSAI 重建。---
6. 已知遗留
source=builtin 规则(如 BUILTIN-、内置 biz-)不回写 SCSAI(设计上 SCSAI 为权威源,内置规则应以 SCSAI 为准)。--both。如需常驻同步可加 cron/定时器调用本脚本。BossAgent_Prompt / BossAgent_Template / BossAgent_BizPrompt 的本地副本仍由 template-sync-service.js 只读拉取,管理界面修改暂不回写 SCSAI(独立待办)。
BossAgents