27 Dead Rules: Root Cause Identification and Cleanup (2026-07-15)
Objective
Address user feedback stating "the system repeatedly fails, unresolved for over a month," focusing on the root cause and closed-loop handling of 27 "dead rules" (unsupported condition type) within the rule engine's contract validation.
Root Cause Conclusion (Not a system defect, but a data classification error)
The sciot_rules_v2 table has no 'type' column; rule types are stored in the JSON of the condition field ({"type":"xxx"}). The engine's supportedTypes whitelist declares 47 types, while _evaluateCondition actually implements 76 cases.
After precise comparison, among 2413 rules:
- 1539 field_check + 695 relationship + other supported types → all are live rules (recognized by the engine).
- Only 27 rules use types not supported by the engine, falling into two categories:
- SCSAI native method types (not handled by the engine, originally SCSAI's responsibility): sequence(7), auto_create(6) — action_type=auto
- Business suggestion types (LLM/SCSAI capabilities, not handled at the engine's condition layer): compare(3), optimize(1), score_check(1), completeness_check(1), trend_compare(1), profit_check(1), stock_level(1), date_check(1), credit_check(1), budget_check(1), consolidation_check(1), aging_analysis(1) — action_type=suggest/validate
These 27 rules were previously kept active with is_active=1 but could never be evaluated by the engine, leading contract validation to mistakenly judge this as a "system defect." The correct approach is not to force them into the engine (which would make them falsely active/always true), but to explicitly retire them.
Fix Actions
- server/core/rule-engine.js L281 Merge loop: Skip rules with is_active=0, no longer loading them into the engine runtime library.
- server/core/rule-engine.js L1344 _checkRuleContract: Added WHERE is_active = 1 to contract validation, only validating active rules.
- Retirement script executed uniformly on sciot_import.db and rule_engine.db: 27 rules with is_active=0, source marked as SCSAI-native-method(13) or business-suggestion-deprecated(14).
- Cleaned up 11 temporary diagnostic scripts (_q_.js / _retire_.js).
Verification Results
- Engine initialize logs: No 'unsupported type' warnings, no 'found N dead rules' messages.
- GET /api/health → 200 {"ok":true}.
- GET /api/rule-engine/stats → total=2413, active=2386 (2386 = 2413−27 retired, numbers closed correctly), 'dead' field removed.
Outstanding Issues (Honestly noted, out of scope for this fix)
- The business capabilities of the 27 retired rules (e.g., supplier price comparison, credit warnings, low inventory alerts) currently have no engine implementation; they rely on SCSAI / LLM side and are not part of the BossAgents local rule engine's responsibility. If localization is needed in the future, their is_active should be restored only after corresponding handlers are added to the engine, not left as-is.
- The root cause of the DB architecture issue (14 unmerged .db files, driver mix mitigated but not fully unified by the better-sqlite3 singleton) remains a separate technical debt.
BossAgents